i.MX93 SPI Driver for MM6108

Are you aware of any successful attempts to support MM6108 in SPI mode with i.MX93 and Linux 6.6.36?

I have configured the device tree as follows:

 &lpspi4 {
	fsl,spi-num-chipselects = <1>;
	pinctrl-names = "default", "sleep";
	pinctrl-0 = <&pinctrl_lpspi4>;
	pinctrl-1 = <&pinctrl_lpspi4>;
	cs-gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;           //MIKROBUS_CS
	status = "okay";
	
	/delete-property/ dmas;      // Disable DMA for now
	/delete-property/ dma-names; // Disable DMA for now

	mm6108_spi: mm6108_spi@0 {
		compatible = "morse,mm610x-spi";
		spi-max-frequency = <1000000>;
		reg = <0>;
		spi-irq-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>;  //MIKROBUS_INT
		reset-gpios = <&pca9555 1 GPIO_ACTIVE_LOW>;   //MIKROBUS_RST
		status = "okay";
	};
};

I see the following on boot:

root@imx93-cargt-00326-00369-ate:/boot# dmesg | grep morse
[    9.300833] morse micro driver registration. Version 0-rel_1_12_4_2024_Jun_11-6-g63cd0768
[    9.311249] morse_spi spi0.0: morse_spi_find_response: SPI response error
[    9.311266] morse_spi spi0.0: morse_spi_probe: SD_IO_RESET
[    9.311306] morse_spi spi0.0: morse_spi_find_response: SPI response error
[    9.311335] morse_spi spi0.0: morse_spi_find_response: SPI response error
[    9.311340] morse_spi spi0.0: morse_spi_probe: SD_IO_RESET
[    9.311367] morse_spi spi0.0: morse_spi_find_response: SPI response error
[    9.311395] morse_spi spi0.0: morse_spi_find_response: SPI response error
[    9.311399] morse_spi spi0.0: morse_spi_probe: SD_IO_RESET
[    9.311426] morse_spi spi0.0: morse_spi_find_response: SPI response error
[    9.311472] morse_spi spi0.0: failed initialise SPI: -71
[    9.317646] morse_spi_probe failed. The driver has not been loaded!
[    9.329959] morse_spi: probe of spi0.0 failed with error -71

The driver ignores the “spi-max-frequency” parameter. I was forced to reduce the MAX_SPI_CLK_SPEED in the driver to 25 MHz because it needs to be half of my peripheral clock (50 MHz).

Here is a Logic Analyzer trace of the SPI bus and RST line on boot.

mm6108_spi_fail.sal (4.5 KB)

Haven’t had any experience with the iMX93 specifically, but we are currently working through a SPI attached iMX6.

A small quirk with the MM6108, in order to put it into SPI mode, the host needs to toggle the SPI clock line ~74 times while the CS pin is held high - ie, inverted compared to normal operation.

From your trace, it looks like yours is driving the CS line low during this period. I suspect this is causing your errors, as the MM6108 then will not respond to any other host commands.
This can happen if the hardware chip select is being used (check pinctrl_lpspi4), and isn’t respecting the driver request to invert the CS logic.

If this is still failing, there may be some kernel patches missing. Let me know!

Here’s how I configured the iMX6 if it helps.

&iomuxc {
	pinctrl_ecspi1_1: ecspi1grp {
		fsl,pins = <
			MX6UL_PAD_CSI_DATA07__ECSPI1_MISO       0x100b1
			MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI       0x100b1
			MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK       0x100b1
			MX6UL_PAD_CSI_DATA05__GPIO4_IO26        0x100b1
		>;
	};

	pinctrl_mm6108: mm6108grp {
		fsl,pins = <
			MX6UL_PAD_CSI_DATA00__GPIO4_IO21        0x100b9
			MX6UL_PAD_CSI_DATA01__GPIO4_IO22        0x100b9
			MX6UL_PAD_CSI_DATA02__GPIO4_IO23        0x100b9
			MX6UL_PAD_CSI_MCLK__GPIO4_IO17          0x100b9
		>;
	};
};

&ecspi1 {
	cs-gpios = <&gpio4 26 1>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_ecspi1_1>;
	status = "okay";

	mm6108: mm6108@0 {
		compatible = "morse,mm610x-spi";
		spi-max-frequency = <50000000>;
		reg = <0>;
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_mm6108>;
		reset-gpios = <&gpio4 21 0>;
		power-gpios = <&gpio4 23 0>,
		              <&gpio4 17 0>;
		spi-irq-gpios = <&gpio4 22 0>;
		status = "okay";
	};
};
1 Like

The pinctrl is treating the CS line as a GPIO.

	pinctrl_lpspi4: lpspi4grp {
		fsl,pins = <
			MX93_PAD_GPIO_IO18__GPIO2_IO18		0x3fe
			MX93_PAD_GPIO_IO07__GPIO2_IO07		0x3fe
			MX93_PAD_GPIO_IO19__LPSPI4_SIN		0x3fe
			MX93_PAD_GPIO_IO20__LPSPI4_SOUT		0x3fe
			MX93_PAD_GPIO_IO21__LPSPI4_SCK		0x3fe
		>;
	};

I am applying the attached kernel patches:
kernel_patches.zip (15.4 KB)

I see what you are saying about the CS line being low during the initialization. I will look into morse_spi_initsequence (spi.c) to see why the CS behavior is not being inverted. Do you think it may be necessary to add a patch to the SPI driver to support this inversion?

It looks like the driver is not respecting the cs_high bit. I see the bit getting set in the debug logs, but I do not see it act as active high on the logic analyzer trace.

[    1.659029] fsl_lpspi 42560000.spi: registered master spi0
[    1.659230] spi spi0.0: setup mode 0, 8 bits/w, 1000000 Hz max --> 0
[    1.659417] fsl_lpspi 42560000.spi: registered child spi0.0
[   11.285861] morse_spi spi0.0: setup mode 0, 8 bits/w, 25000000 Hz max --> 0
[   11.285912] morse_spi spi0.0: setup mode 0, cs_high, 8 bits/w, 25000000 Hz max --> 0
[   11.285961] fsl_lpspi 42560000.spi: perclk=50000000, speed=25000000, prescale=0, scldiv=0
[   11.285968] fsl_lpspi 42560000.spi: FCR=0x4
[   11.285973] fsl_lpspi 42560000.spi: TCR=0x7
[   11.286320] fsl_lpspi 42560000.spi: fsl_lpspi_dma_tx_callback
[   11.286339] fsl_lpspi 42560000.spi: fsl_lpspi_dma_rx_callback
[   11.290560] morse_spi spi0.0: setup mode 0, 8 bits/w, 25000000 Hz max --> 0
[   11.290608] fsl_lpspi 42560000.spi: perclk=50000000, speed=25000000, prescale=0, scldiv=0
[   11.290614] fsl_lpspi 42560000.spi: FCR=0x4
[   11.290619] fsl_lpspi 42560000.spi: TCR=0x7
[   11.290694] fsl_lpspi 42560000.spi: fsl_lpspi_dma_tx_callback
[   11.290708] fsl_lpspi 42560000.spi: fsl_lpspi_dma_rx_callback
[   11.291302] morse_spi spi0.0: morse_spi_find_response: SPI response error
[   11.291316] morse_spi spi0.0: morse_spi_probe: SD_IO_RESET
[   11.291343] fsl_lpspi 42560000.spi: perclk=50000000, speed=25000000, prescale=0, scldiv=0
[   11.291350] fsl_lpspi 42560000.spi: FCR=0x4
[   11.291355] fsl_lpspi 42560000.spi: TCR=0x7
[   11.291422] fsl_lpspi 42560000.spi: fsl_lpspi_dma_tx_callback
[   11.291432] fsl_lpspi 42560000.spi: fsl_lpspi_dma_rx_callback
[   11.291499] morse_spi spi0.0: morse_spi_find_response: SPI response error
[   11.291513] fsl_lpspi 42560000.spi: perclk=50000000, speed=25000000, prescale=0, scldiv=0
[   11.291519] fsl_lpspi 42560000.spi: FCR=0x4
[   11.291523] fsl_lpspi 42560000.spi: TCR=0x7
[   11.291569] fsl_lpspi 42560000.spi: fsl_lpspi_dma_tx_callback
[   11.291576] fsl_lpspi 42560000.spi: fsl_lpspi_dma_rx_callback
[   11.291849] morse_spi spi0.0: morse_spi_find_response: SPI response error
[   11.291857] morse_spi spi0.0: morse_spi_probe: SD_IO_RESET
[   11.291872] fsl_lpspi 42560000.spi: perclk=50000000, speed=25000000, prescale=0, scldiv=0
[   11.291879] fsl_lpspi 42560000.spi: FCR=0x4
[   11.291883] fsl_lpspi 42560000.spi: TCR=0x7
[   11.291936] fsl_lpspi 42560000.spi: fsl_lpspi_dma_tx_callback
[   11.291947] fsl_lpspi 42560000.spi: fsl_lpspi_dma_rx_callback
[   11.291959] morse_spi spi0.0: morse_spi_find_response: SPI response error
[   11.291970] fsl_lpspi 42560000.spi: perclk=50000000, speed=25000000, prescale=0, scldiv=0
[   11.291976] fsl_lpspi 42560000.spi: FCR=0x4
[   11.291980] fsl_lpspi 42560000.spi: TCR=0x7
[   11.292021] fsl_lpspi 42560000.spi: fsl_lpspi_dma_tx_callback
[   11.292028] fsl_lpspi 42560000.spi: fsl_lpspi_dma_rx_callback
[   11.292061] morse_spi spi0.0: morse_spi_find_response: SPI response error
[   11.292066] morse_spi spi0.0: morse_spi_probe: SD_IO_RESET
[   11.292076] fsl_lpspi 42560000.spi: perclk=50000000, speed=25000000, prescale=0, scldiv=0
[   11.292082] fsl_lpspi 42560000.spi: FCR=0x4
[   11.292086] fsl_lpspi 42560000.spi: TCR=0x7
[   11.292124] fsl_lpspi 42560000.spi: fsl_lpspi_dma_tx_callback
[   11.292132] fsl_lpspi 42560000.spi: fsl_lpspi_dma_rx_callback
[   11.292368] morse_spi spi0.0: morse_spi_find_response: SPI response error
[   11.292375] morse_spi spi0.0: failed initialise SPI: -71
[   11.299216] morse_spi_probe failed. The driver has not been loaded!
[   11.306125] morse_spi: probe of spi0.0 failed with error -71

@ajudge I was using the 1.12.4 version of the driver. It is missing some kernel changes related to SPI_CONTROLLER_ENABLE_CS_GPIOD.

I upgraded to 1.14.1 and pulled in the new kernel patches. I am able to load the driver successfully now and I do see the CS line inverted for the initialization.

I still have to modify the driver to limit the SPI bus speed to 25 MHz. Is it possible add support to the driver to respect the spi-max-frequency property?

There is a module parameter spi_clock_speed which you can set on driver insertion to set the module parameter. However, I can appreciate that you would want to communicate this configuration with devicetree instead. We did have an internal patch which was never merged to respect the device tree property, I’ll follow that up.