How to Configure DTS and Struct for SPI Controller Driver with Child Nodes in Zephyr?
Hello Guys,
I am developing a SPI Controller Driver for TI processors for Zephyr,
I have a doubt on how do i set the Dts to look like?
ideally it should like this if we include soc.dtsi, board.dts, overlay.dts
&spi1 {
compatible = "ti,omap-spi";
reg = <0x48030000 0x1000>;
interrupts = <25>;
#address-cells = <1>;
#size-cells = <0>;
spi1_device0: spi-device@0 {
reg = <0>;
spi-max-frequency = <1000000>;
spi-cs-delay = <5>;
word_length = <8>
};
spi1_device1: spi-device@1 {
reg = <1>;
spi-max-frequency = <2000000>;
spi-cs-delay = <10>;
word_length = <32>
};
};
As of now, I am getting the SPI controller to have 4 CS, no DMA, no slave mode
how do i set my struct config to accomodate the above?
it would be simple if there was no child nodes
like the below
struct spi_omap_config {
DEVICE_MMIO_NAMED_ROM(base);
uint32_t irq;
};
but with child nodes in the equation, i am so confused...18 Replies
will have some time later Ill try and reproduce this.
Ok now on this, wait so you have a driver and that is fine, what you want is to be able to control 4 devices off of your driver and no DMA and while being master right?
@melta101 if the above is correct you need to define your CS lines in the overlay as GPIOS
and if you have enabled DMA in your controller driver you need to override the dma feature in your overlay
Let me know If I am looking at this too simply
What if you define a struct for a child node. Then in your config you have an array of the children like so
const struct spi_children_dev childs[4];
. This way you could parse the device tree and initialize each child node. What if.sorry for the delay..
Yep,
That's the plan
but in this case, we dont need to use GPIO to activate it,
there are register to do those stuffs
makes sense
i was thinking something similar
but how do i define the API init macros?
lets take the above example
reg -> array
interupt -> array
but as what type, do we define those child nodes?
i was thinking of passing it as array itself
but those would mean
instead of
spi1_device0: spi-device@0 {
reg = <0>;
spi-max-frequency = <1000000>;
spi-cs-delay = <5>;
word_length = <8>
};
it would be become
spi1_device0:spi-device@0 = <0 100000 5 8>
What about just capturing that data.
struct spi_omap_device {
uint32_t reg;
uint32_t spi_max_freq;
uint32_t spi_cs_delay;
uint32_t word_length;
};
The creating an init macro that we call using DT_INST_FOREACH_CHILD
Something like
Will try the above once i reach back
Thanks
ah I see
the define macros should look like this
#define SPI_OMAP_DEVICE_INIT(inst) \
static const struct spi_cs_omap_config spi_cs_omapconfig##inst[] = SPI_SENSOR_CONFIG_ARRAY(inst); \
static struct spi_omap_config spi_omapconfig##inst = { \
DEVICE_MMIO_NAMED_ROM_INIT(DT_INST_REG_ADDR(inst)), \
.irq = DT_INST_IRQN(inst), \
.cs_config = spi_cs_omapconfig##inst, \
};
if i am not wrong
that way
We can write the dts like below
soc.dtsi
/soc {
spi0: spi@48030000 {
compatible = "ti,omap-spi";
reg = <0x48030000 0x1000>;
interrupts = <41>;
spi-max-frequency = <48000000>;
status = "disabled";
};
};
board.dts
&spi0 {
status = "okay";
};
};
sensor.overlay
&spi0 {
sensor@0 {
compatible = "generic,sensor";
reg = <0>;
frequency = <12000000>;
ti,cs-delay = <10>;
label = "SENSOR_0";
};
sensor@1 {
compatible = "generic,sensor";
reg = <1>;
frequency = <24000000>;
ti,cs-delay = <20>;
label = "SENSOR_1";
};
};
i suppose the above is acceptable for zephyr style of application programmingyes this looks good to me.
ultimate PR review right there mate