arm64/imx9: Add LPSPI driver

Add driver for LPSPI

Co-authored-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
This commit is contained in:
Ville Juven 2024-04-02 15:30:02 +03:00 committed by Alan Carvalho de Assis
parent 8d4eae41c1
commit d73aab9f71
11 changed files with 2891 additions and 0 deletions

View File

@ -301,6 +301,10 @@ config IMX9_LPI2C
bool "LPI2C support"
default n
config IMX9_LPSPI
bool "LPSPI support"
default n
config IMX9_PLL
bool "PLL setup support (WIP)"
default n
@ -496,6 +500,51 @@ config IMX9_LPI2C8_FILTSDA
endif # IMX9_LPI2C8
endmenu # LPI2C Peripherals
menu "LPSPI Peripherals"
menuconfig IMX9_LPSPI1
bool "LPSPI1"
default n
select IMX9_LPSPI
menuconfig IMX9_LPSPI2
bool "LPSPI2"
default n
select IMX9_LPSPI
menuconfig IMX9_LPSPI3
bool "LPSPI3"
default n
select IMX9_LPSPI
menuconfig IMX9_LPSPI4
bool "LPSPI4"
default n
select IMX9_LPSPI
menuconfig IMX9_LPSPI5
bool "LPSPI5"
default n
select IMX9_LPSPI
menuconfig IMX9_LPSPI6
bool "LPSPI6"
default n
select IMX9_LPSPI
menuconfig IMX9_LPSPI7
bool "LPSPI7"
default n
select IMX9_LPSPI
menuconfig IMX9_LPSPI8
bool "LPSPI8"
default n
select IMX9_LPSPI
endmenu # LPSPI Peripherals
menu "LPI2C Configuration"
depends on IMX9_LPI2C
@ -550,4 +599,81 @@ config IMX9_LPI2C_TIMEOTICKS
endmenu # LPI2C Configuration
menu "LPSPI Configuration"
depends on IMX9_LPSPI
config IMX9_LPSPI_DMA
bool "LPSPI DMA"
depends on IMX9_EDMA
default n
---help---
Use DMA to improve LPSPI transfer performance.
config IMX9_LPSPI_DMATHRESHOLD
int "LPSPI DMA threshold"
default 4
depends on IMX9_LPSPI_DMA
---help---
When SPI DMA is enabled, small DMA transfers will still be performed
by polling logic. But we need a threshold value to determine what
is small.
config IMX9_LPSPI1_DMA
bool "LPSPI1 DMA"
default n
depends on IMX9_LPSPI1 && IMX9_LPSPI_DMA
---help---
Use DMA to improve LPSPI1 transfer performance.
config IMX9_LPSPI2_DMA
bool "LPSPI2 DMA"
default n
depends on IMX9_LPSPI2 && IMX9_LPSPI_DMA
---help---
Use DMA to improve LPSPI2 transfer performance.
config IMX9_LPSPI3_DMA
bool "LPSPI3 DMA"
default n
depends on IMX9_LPSPI3 && IMX9_LPSPI_DMA
---help---
Use DMA to improve LPSPI3 transfer performance.
config IMX9_LPSPI4_DMA
bool "LPSPI4 DMA"
default n
depends on IMX9_LPSPI4 && IMX9_LPSPI_DMA
---help---
Use DMA to improve SPI4 transfer performance.
config IMX9_LPSPI5_DMA
bool "LPSPI5 DMA"
default n
depends on IMX9_LPSPI5 && IMX9_LPSPI_DMA
---help---
Use DMA to improve SPI5 transfer performance.
config IMX9_LPSPI6_DMA
bool "LPSPI6 DMA"
default n
depends on IMX9_LPSPI6 && IMX9_LPSPI_DMA
---help---
Use DMA to improve SPI6 transfer performance.
config IMX9_LPSPI7_DMA
bool "LPSPI7 DMA"
default n
depends on IMX9_LPSPI7 && IMX9_LPSPI_DMA
---help---
Use DMA to improve SPI7 transfer performance.
config IMX9_LPSPI8_DMA
bool "LPSPI8 DMA"
default n
depends on IMX9_LPSPI8 && IMX9_LPSPI_DMA
---help---
Use DMA to improve SPI8 transfer performance.
endmenu # LPSPI Configuration
endif # ARCH_CHIP_IMX9

View File

@ -47,3 +47,7 @@ endif
ifeq ($(CONFIG_IMX9_LPI2C),y)
CHIP_CSRCS += imx9_lpi2c.c
endif
ifeq ($(CONFIG_IMX9_LPSPI), y)
CHIP_CSRCS += imx9_lpspi.c
endif

View File

@ -0,0 +1,351 @@
/****************************************************************************
* arch/arm64/src/imx9/hardware/imx9_lpspi.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_LPSPI_H_
#define __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_LPSPI_H_
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Register offsets *********************************************************/
#define IMX9_LPSPI_VERID_OFFSET (0x0000) /* Version ID Register (VERID) */
#define IMX9_LPSPI_PARAM_OFFSET (0x0004) /* Parameter Register (PARAM) */
#define IMX9_LPSPI_CR_OFFSET (0x0010) /* Control Register (CR) */
#define IMX9_LPSPI_SR_OFFSET (0x0014) /* Status Register (SR) */
#define IMX9_LPSPI_IER_OFFSET (0x0018) /* Interrupt Enable Register (IER) */
#define IMX9_LPSPI_DER_OFFSET (0x001c) /* DMA Enable Register (DER) */
#define IMX9_LPSPI_CFGR0_OFFSET (0x0020) /* Configuration Register 0 (CFGR0) */
#define IMX9_LPSPI_CFGR1_OFFSET (0x0024) /* Configuration Register 1 (CFGR1) */
#define IMX9_LPSPI_DMR0_OFFSET (0x0030) /* Data Match Register 0 (DMR0) */
#define IMX9_LPSPI_DMR1_OFFSET (0x0034) /* Data Match Register 1 (DMR1) */
#define IMX9_LPSPI_CCR_OFFSET (0x0040) /* Clock Configuration Register (CCR) */
#define IMX9_LPSPI_CCR1_OFFSET (0x0044) /* Clock Configuration Register 1 (CCR1) */
#define IMX9_LPSPI_FCR_OFFSET (0x0058) /* FIFO Control Register (FCR) */
#define IMX9_LPSPI_FSR_OFFSET (0x005c) /* FIFO Status Register (FSR) */
#define IMX9_LPSPI_TCR_OFFSET (0x0060) /* Transmit Command Register (TCR) */
#define IMX9_LPSPI_TDR_OFFSET (0x0064) /* Transmit Data Register (TDR) */
#define IMX9_LPSPI_RSR_OFFSET (0x0070) /* Receive Status Register (RSR) */
#define IMX9_LPSPI_RDR_OFFSET (0x0074) /* Receive Data Register (RDR) */
#define IMX9_LPSPI_RDROR_OFFSET (0x0078) /* Receive Data Read Only Register (RDROR) */
#define IMX9_LPSPI_TCBR_OFFSET (0x03fc) /* Transmit Command Burst Register (TCBR) */
#define IMX9_LPSPI_TDBR_OFFSET(n) (0x0400 + ((n) << 2)) /* Transmit Data Burst Register n=0..127 (TDBRn) */
#define IMX9_LPSPI_RDBR_OFFSET(n) (0x0600 + ((n) << 2)) /* Receive Data Burst Register n=0..127 (RDBRn) */
/* Register addresses *******************************************************/
#define IMX9_LPSPI0_VERID(n) ((n) + IMX9_LPSPI_VERID_OFFSET)
#define IMX9_LPSPI0_PARAM(n) ((n) + IMX9_LPSPI_PARAM_OFFSET)
#define IMX9_LPSPI0_CR(n) ((n) + IMX9_LPSPI_CR_OFFSET)
#define IMX9_LPSPI0_SR(n) ((n) + IMX9_LPSPI_SR_OFFSET)
#define IMX9_LPSPI0_IER(n) ((n) + IMX9_LPSPI_IER_OFFSET)
#define IMX9_LPSPI0_DER(n) ((n) + IMX9_LPSPI_DER_OFFSET)
#define IMX9_LPSPI0_CFGR0(n) ((n) + IMX9_LPSPI_CFGR0_OFFSET)
#define IMX9_LPSPI0_CFGR1(n) ((n) + IMX9_LPSPI_CFGR1_OFFSET)
#define IMX9_LPSPI0_DMR0(n) ((n) + IMX9_LPSPI_DMR0_OFFSET)
#define IMX9_LPSPI0_DMR1(n) ((n) + IMX9_LPSPI_DMR1_OFFSET)
#define IMX9_LPSPI0_CCR(n) ((n) + IMX9_LPSPI_CCR_OFFSET)
#define IMX9_LPSPI0_CCR1(n) ((n) + IMX9_LPSPI_CCR1_OFFSET)
#define IMX9_LPSPI0_FCR(n) ((n) + IMX9_LPSPI_FCR_OFFSET)
#define IMX9_LPSPI0_FSR(n) ((n) + IMX9_LPSPI_FSR_OFFSET)
#define IMX9_LPSPI0_TCR(n) ((n) + IMX9_LPSPI_TCR_OFFSET)
#define IMX9_LPSPI0_TDR(n) ((n) + IMX9_LPSPI_TDR_OFFSET)
#define IMX9_LPSPI0_RSR(n) ((n) + IMX9_LPSPI_RSR_OFFSET)
#define IMX9_LPSPI0_RDR(n) ((n) + IMX9_LPSPI_RDR_OFFSET)
#define IMX9_LPSPI0_RDROR(n) ((n) + IMX9_LPSPI_RDROR_OFFSET)
#define IMX9_LPSPI0_TCBR(n) ((n) + IMX9_LPSPI_TCBR_OFFSET)
#define IMX9_LPSPI0_TDBR(n,v) ((n) + IMX9_LPSPI_TDBR_OFFSET(v))
#define IMX9_LPSPI0_RDBR(n,v) ((n) + IMX9_LPSPI_RDBR_OFFSET(v))
/* Register bit definitions *************************************************/
/* Version ID Register (VERID) */
#define LPSPI_VERID_FEATURE_SHIFT (0) /* Bits 0-15: Module Identification Number (FEATURE) */
#define LPSPI_VERID_FEATURE_MASK (0xffff << LPSPI_VERID_FEATURE_SHIFT)
#define LPSPI_VERID_MINOR_SHIFT (16) /* Bits 16-23: Minor Version Number (MINOR) */
#define LPSPI_VERID_MINOR_MASK (0xff << LPSPI_VERID_MINOR_SHIFT)
#define LPSPI_VERID_MAJOR_SHIFT (24) /* Bits 24-31: Major Version Number (MAJOR) */
#define LPSPI_VERID_MAJOR_MASK (0xff << LPSPI_VERID_MAJOR_SHIFT)
/* Parameter Register (PARAM) */
#define LPSPI_PARAM_TXFIFO_SHIFT (0) /* Bits 0-7: Transmit FIFO Size (TXFIFO) */
#define LPSPI_PARAM_TXFIFO_MASK (0xff << LPSPI_PARAM_TXFIFO_SHIFT)
#define LPSPI_PARAM_RXFIFO_SHIFT (8) /* Bits 8-15: Receive FIFO Size (RXFIFO) */
#define LPSPI_PARAM_RXFIFO_MASK (0xff << LPSPI_PARAM_RXFIFO_SHIFT)
#define LPSPI_PARAM_PCSNUM_SHIFT (16) /* Bits 16-23: PCS Number (PCSNUM) */
#define LPSPI_PARAM_PCSNUM_MASK (0xff << LPSPI_PARAM_PCSNUM_SHIFT)
/* Bits 24-31: Reserved */
/* Control Register (CR) */
#define LPSPI_CR_MEN (1 << 0) /* Bit 0: Module Enable (MEN) */
#define LPSPI_CR_RST (1 << 1) /* Bit 1: Software Reset (RST) */
/* Bit 2: Reserved */
#define LPSPI_CR_DBGEN (1 << 3) /* Bit 3: Debug Enable (DBGEN) */
/* Bits 4-7: Reserved */
#define LPSPI_CR_RTF (1 << 8) /* Bit 8: Reset Transmit FIFO (RTF) */
#define LPSPI_CR_RRF (1 << 9) /* Bit 9: Reset Receive FIFO (RRF) */
/* Bits 10-31: Reserved */
/* Status Register (SR) */
#define LPSPI_SR_TDF (1 << 0) /* Bit 0: Transmit Data Flag (TDF) */
#define LPSPI_SR_RDF (1 << 1) /* Bit 1: Receive Data Flag (RDF) */
/* Bits 2-7: Reserved */
#define LPSPI_SR_WCF (1 << 8) /* Bit 8: Word Complete Flag (WCF) */
#define LPSPI_SR_FCF (1 << 9) /* Bit 9: Frame Complete Flag (FCF) */
#define LPSPI_SR_TCF (1 << 10) /* Bit 10: Transfer Complete Flag (TCF) */
#define LPSPI_SR_TEF (1 << 11) /* Bit 11: Transmit Error Flag (TEF) */
#define LPSPI_SR_REF (1 << 12) /* Bit 12: Receive Error Flag (REF) */
#define LPSPI_SR_DMF (1 << 13) /* Bit 13: Data Match Flag (DMF) */
/* Bits 14-23: Reserved */
#define LPSPI_SR_MBF (1 << 24) /* Bit 24: Module Busy Flag (MBF) */
/* Bits 25-31: Reserved */
/* Interrupt Enable Register (IER) */
#define LPSPI_IER_TDIE (1 << 0) /* Bit 0: Transmit Data Interrupt Enable (TDIE) */
#define LPSPI_IER_RDIE (1 << 1) /* Bit 1: Receive Data Interrupt Enable (RDIE) */
/* Bits 2-7: Reserved */
#define LPSPI_IER_WCIE (1 << 8) /* Bit 8: Word Complete Interrupt Enable (WCIE) */
#define LPSPI_IER_FCIE (1 << 9) /* Bit 9: Frame Complete Interrupt Enable (FCIE) */
#define LPSPI_IER_TCIE (1 << 10) /* Bit 10: Transfer Complete Interrupt Enable (TCIE) */
#define LPSPI_IER_TEIE (1 << 11) /* Bit 11: Transmit Error Interrupt Enable (TEIE) */
#define LPSPI_IER_REIE (1 << 12) /* Bit 12: Receive Error Interrupt Enable (REIE) */
#define LPSPI_IER_DMIE (1 << 13) /* Bit 13: Data Match Interrupt Enable (DMIE) */
/* Bits 14-31: Reserved */
/* DMA Enable Register (DER) */
#define LPSPI_DER_TDDE (1 << 0) /* Bit 0: Transmit Data DMA Enable (TDDE) */
#define LPSPI_DER_RDDE (1 << 1) /* Bit 1: Receive Data DMA Enable (RDDE) */
/* Bits 2-31: Reserved */
/* Configuration Register 0 (CFGR0) */
#define LPSPI_CFGR0_HREN (1 << 0) /* Bit 0: Host Request Enable (HREN) */
#define LPSPI_CFGR0_HRPOL (1 << 1) /* Bit 1: Host Request Polarity (HRPOL) */
# define LPSPI_CFGR0_HRPOL_HIGH (0 << 1) /* HREQ pin or input trigger is active high */
# define LPSPI_CFGR0_HRPOL_LOW (1 << 1) /* HREQ pin or input trigger is active low */
#define LPSPI_CFGR0_HRSEL (1 << 2) /* Bit 2: Host Request Select (HRSEL) */
# define LPSPI_CFGR0_HRSEL_HREQ (0 << 2) /* Host request input is the LPSPI_HREQ pin */
# define LPSPI_CFGR0_HRSEL_INTR (1 << 2) /* Host request input is the input trigger */
#define LPSPI_CFGR0_HRDIR (1 << 3) /* Bit 3: Host Request Direction (HRDIR) */
# define LPSPI_CFGR0_HRDIR_INPUT (0 << 3) /* HREQ pin is configured as input */
# define LPSPI_CFGR0_HRDIR_OUTPUT (1 << 3) /* HREQ pin is configured as output */
/* Bits 4-7: Reserved */
#define LPSPI_CFGR0_CIRFIFO (1 << 8) /* Bit 8: Circular FIFO Enable (CIRCFIFO) */
#define LPSPI_CFGR0_RDMO (1 << 9) /* Bit 9: Receive Data Match Only (RDMO) */
# define LPSPI_CFGR0_RDMO_FIFO (0 << 9) /* Received data is stored in the receive FIFO as in normal operations */
# define LPSPI_CFGR0_RDMO_DMF (1 << 9) /* Received data is discarded unless the Data Match Flag (DMF) is set */
/* Bits 10-31: Reserved */
/* Configuration Register 1 (CFGR1) */
#define LPSPI_CFGR1_MASTER (1 << 0) /* Bit 0: Master Mode (MASTER) */
#define LPSPI_CFGR1_SAMPLE (1 << 1) /* Bit 1: Sample Point (SAMPLE) */
# define LPSPI_CFGR1_SAMPLE_SCK (0 << 1) /* Input data is sampled on SCK edge */
# define LPSPI_CFGR1_SAMPLE_DELAY (1 << 1) /* Input data is sampled on delayed SCK edge */
#define LPSPI_CFGR1_AUTOPCS (1 << 2) /* Bit 2: Automatic PCS (AUTOPCS) */
#define LPSPI_CFGR1_NOSTALL (1 << 3) /* Bit 3: No Stall (NOSTALL) */
#define LPSPI_CFGR1_PARTIAL (1 << 4) /* Bit 4: Partial Enable (PARTIAL) */
/* Bits 5-7: Reserved */
#define LPSPI_CFGR1_PCSPOL_SHIFT (8) /* Bits 8-15: Peripheral Chip Select Polarity (PCSPOL) */
#define LPSPI_CFGR1_PCSPOL_MASK (0xff << LPSPI_CFGR1_PCSPOL_SHIFT)
# define LPSPI_CFGR1_PCSPOL_LOW(n) (0 << (LPSPI_CFGR1_PCSPOL_SHIFT + (n))) /* The Peripheral Chip Select PCS[n] pin is active low */
# define LPSPI_CFGR1_PCSPOL_HIGH(n) (1 << (LPSPI_CFGR1_PCSPOL_SHIFT + (n))) /* The Peripheral Chip Select PCS[n] pin is active high */
#define LPSPI_CFGR1_MATCFG_SHIFT (16) /* Bits 16-18: Match Configuration (MATCFG) */
#define LPSPI_CFGR1_MATCFG_MASK (0x07 << LPSPI_CFGR1_MATCFG_SHIFT)
#define LPSPI_CFGR1_MATCFG_DIS (0x00 << LPSPI_CFGR1_MATCFG_SHIFT) /* Match is disabled */
/* Bits 19-23: Reserved */
#define LPSPI_CFGR1_PINCFG_SHIFT (24) /* Bits 24-25: Pin Configuration (PINCFG) */
#define LPSPI_CFGR1_PINCFG_MASK (0x03 << LPSPI_CFGR1_PINCFG_SHIFT)
# define LPSPI_CFGR1_PINCFG_SIN_SOUT (0x00 << LPSPI_CFGR1_PINCFG_SHIFT) /* SIN is used for input data and SOUT is used for output data */
# define LPSPI_CFGR1_PINCFG_SIN_SIN (0x01 << LPSPI_CFGR1_PINCFG_SHIFT) /* SIN is used for both input and output data */
# define LPSPI_CFGR1_PINCFG_SOUT_SOUT (0x02 << LPSPI_CFGR1_PINCFG_SHIFT) /* SOUT is used for both input and output data */
# define LPSPI_CFGR1_PINCFG_SOUT_SIN (0x03 << LPSPI_CFGR1_PINCFG_SHIFT) /* SOUT is used for input data and SIN is used for output data */
# define LPSPI_CFGR1_PINCFG(n) ((n) << LPSPI_CFGR1_PINCFG_SHIFT)
#define LPSPI_CFGR1_OUTCFG (1 << 26) /* Bit 26: Output Config (OUTCFG) */
# define LPSPI_CFGR1_OUTCFG_RETAIN (0 << 26) /* Output data retains last value when chip select is negated */
# define LPSPI_CFGR1_OUTCFG_TRISTATE (1 << 26) /* Output data is tristated when chip select is negated */
#define LPSPI_CFGR1_PCSCFG_SHIFT (27) /* Bits 27-28: Peripheral Chip Select Configuration (PCSCFG) */
#define LPSPI_CFGR1_PCSCFG_MASK (0x03 << LPSPI_CFGR1_PCSCFG_SHIFT)
# define LPSPI_CFGR1_PCSCFG_PCS (0x00 << LPSPI_CFGR1_PCSCFG_SHIFT) /* PCS[2:7] are configured for chip select function */
# define LPSPI_CFGR1_PCSCFG_4BIT (0x01 << LPSPI_CFGR1_PCSCFG_SHIFT) /* PCS[2:3] are configured for half-duplex 4-bit transfers */
# define LPSPI_CFGR1_PCSCFG_8BIT (0x03 << LPSPI_CFGR1_PCSCFG_SHIFT) /* PCS[2:7] are configured for half-duplex 4-bit and 8-bit transfers */
/* Bits 29-31: Reserved */
/* Data Match Register 0 (DMR0) */
#define LPSPI_DMR0_MATCH0_SHIFT (0) /* Bits 0-31: Match 0 Value (MATCH0) */
#define LPSPI_DMR0_MATCH0_MASK (0xffffffff << LPSPI_DMR0_MATCH0_SHIFT)
/* Data Match Register 0 (DMR1) */
#define LPSPI_DMR1_MATCH1_SHIFT (0) /* Bits 0-31: Match 1 Value (MATCH1) */
#define LPSPI_DMR1_MATCH1_MASK (0xffffffff << LPSPI_DMR1_MATCH1_SHIFT)
/* Clock Configuration Register (CCR) */
#define LPSPI_CCR_SCKDIV_SHIFT (0) /* Bits 0-7: SCK Divider (SCKDIV) */
#define LPSPI_CCR_SCKDIV_MASK (0xff << LPSPI_CCR_SCKDIV_SHIFT)
# define LPSPI_CCR_SCKDIV(n) (((uint32_t)(n) << LPSPI_CCR_SCKDIV_SHIFT) & LPSPI_CCR_SCKDIV_MASK)
#define LPSPI_CCR_DBT_SHIFT (8) /* Bits 8-15: Delay Between Transfers (DBT) */
#define LPSPI_CCR_DBT_MASK (0xff << LPSPI_CCR_DBT_SHIFT)
# define LPSPI_CCR_DBT(n) (((uint32_t)(n) << LPSPI_CCR_DBT_SHIFT) & LPSPI_CCR_DBT_MASK)
#define LPSPI_CCR_PCSSCK_SHIFT (16) /* Bits 16-23: PCS-to-SCK Delay (PCSSCK) */
#define LPSPI_CCR_PCSSCK_MASK (0xff << LPSPI_CCR_PCSSCK_SHIFT)
# define LPSPI_CCR_PCSSCK(n) (((uint32_t)(n) << LPSPI_CCR_PCSSCK_SHIFT) & LPSPI_CCR_PCSSCK_MASK)
#define LPSPI_CCR_SCKPCS_SHIFT (24) /* Bits 24-31: SCK-to-PCS Delay (SCKPCS) */
#define LPSPI_CCR_SCKPCS_MASK (0xff << LPSPI_CCR_SCKPCS_SHIFT)
# define LPSPI_CCR_SCKPCS(n) (((uint32_t)(n) << LPSPI_CCR_SCKPCS_SHIFT) & LPSPI_CCR_SCKPCS_MASK)
/* Clock Configuration Register 1 (CCR1) */
#define LPSPI_CCR1_SCKSET_SHIFT (0) /* Bits 0-7: SCK Setup (SCKSET) */
#define LPSPI_CCR1_SCKSET_MASK (0xff << LPSPI_CCR1_SCKSET_SHIFT)
#define LPSPI_CCR1_SCKHLD_SHIFT (8) /* Bits 8-15: SCK Hold (SCKHLD) */
#define LPSPI_CCR1_SCKHLD_MASK (0xff << LPSPI_CCR1_SCKHLD_SHIFT)
#define LPSPI_CCR1_PCSPCS_SHIFT (16) /* Bits 16-23: PCS to PCS Delay (PCSPCS) */
#define LPSPI_CCR1_PCSPCS_MASK (0xff << LPSPI_CCR1_PCSPCS_SHIFT)
#define LPSPI_CCR1_SCKSCK_SHIFT (24) /* Bits 24-31: SCK Inter-Frame Delay (SCKSCK) */
#define LPSPI_CCR1_SCKSCK_MASK (0xff << LPSPI_CCR1_SCKSCK_SHIFT)
/* FIFO Control Register (FCR) */
#define LPSPI_FCR_TXWATER_SHIFT (0) /* Bits 0-1: Transmit FIFO Watermark (TXWATER) */
#define LPSPI_FCR_TXWATER_MASK (0x03 << LPSPI_FCR_TXWATER_SHIFT)
# define LPSPI_FCR_TXWATER(n) ((uint32_t)(n) << LPSPI_FCR_TXWATER_SHIFT)
/* Bits 2-15: Reserved */
#define LPSPI_FCR_RXWATER_SHIFT (16) /* Bits 16-17: Receive FIFO Watermark (RXWATER) */
#define LPSPI_FCR_RXWATER_MASK (0x03 << LPSPI_FCR_RXWATER_SHIFT)
# define LPSPI_FCR_RXWATER(n) ((uint32_t)(n) << LPSPI_FCR_RXWATER_SHIFT)
/* Bits 18-31: Reserved */
/* FIFO Status Register (FSR) */
#define LPSPI_FSR_TXCOUNT_SHIFT (0) /* Bits 0-2: Transmit FIFO Count (TXCOUNT) */
#define LPSPI_FSR_TXCOUNT_MASK (0x07 << LPSPI_FSR_TXCOUNT_SHIFT)
/* Bits 3-15: Reserved */
#define LPSPI_FSR_RXCOUNT_SHIFT (16) /* Bits 16-18: Receive FIFO Count (RXCOUNT) */
#define LPSPI_FSR_RXCOUNT_MASK (0x07 << LPSPI_FSR_RXCOUNT_SHIFT)
/* Bits 19-31: Reserved */
/* Transmit Command Register (TCR) */
#define LPSPI_TCR_FRAMESZ_SHIFT (0) /* Bits 0-11: Frame Size (FRAMESZ) */
#define LPSPI_TCR_FRAMESZ_MASK (0x0fff << LPSPI_TCR_FRAMESZ_SHIFT)
# define LPSPI_TCR_FRAMESZ(n) ((uint32_t)(n) << LPSPI_TCR_FRAMESZ_SHIFT)
/* Bits 12-15: Reserved */
#define LPSPI_TCR_WIDTH_SHIFT (16) /* Bits 16-17: Transfer Width (WIDTH) */
#define LPSPI_TCR_WIDTH_MASK (0x03 << LPSPI_TCR_WIDTH_SHIFT)
# define LPSPI_TCR_WIDTH_1BIT (0x00 << LPSPI_TCR_WIDTH_SHIFT) /* 1 bit transfer */
# define LPSPI_TCR_WIDTH_2BIT (0x01 << LPSPI_TCR_WIDTH_SHIFT) /* 2 bit transfer */
# define LPSPI_TCR_WIDTH_4BIT (0x02 << LPSPI_TCR_WIDTH_SHIFT) /* 4 bit transfer */
# define LPSPI_TCR_WIDTH_8BIT (0x03 << LPSPI_TCR_WIDTH_SHIFT) /* 8 bit transfer */
#define LPSPI_TCR_TXMSK (1 << 18) /* Bit 18: Transmit Data Mask (TXMSK) */
#define LPSPI_TCR_RXMSK (1 << 19) /* Bit 19: Receive Data Mask (RXMSK) */
#define LPSPI_TCR_CONTC (1 << 20) /* Bit 20: Continuing Command (CONTC) */
#define LPSPI_TCR_CONT (1 << 21) /* Bit 21: Continuous Transfer (CONT) */
#define LPSPI_TCR_BYSW (1 << 22) /* Bit 22: Byte Swap (BYSW) */
#define LPSPI_TCR_LSBF (1 << 23) /* Bit 23: LSB First (LSBF) */
# define LPSPI_TCR_MSBF (0 << 23) /* MSB First */
#define LPSPI_TCR_PCS_SHIFT (24) /* Bits 24-26: Peripheral Chip Select (PCS) */
#define LPSPI_TCR_PCS_MASK (0x07 << LPSPI_TCR_PCS_SHIFT)
# define LPSPI_TCR_PCS_0 (0x00 << LPSPI_TCR_PCS_SHIFT) /* Transfer using PCS[0] */
# define LPSPI_TCR_PCS_1 (0x01 << LPSPI_TCR_PCS_SHIFT) /* Transfer using PCS[1] */
# define LPSPI_TCR_PCS_2 (0x02 << LPSPI_TCR_PCS_SHIFT) /* Transfer using PCS[2] */
# define LPSPI_TCR_PCS_3 (0x03 << LPSPI_TCR_PCS_SHIFT) /* Transfer using PCS[3] */
# define LPSPI_TCR_PCS_4 (0x04 << LPSPI_TCR_PCS_SHIFT) /* Transfer using PCS[4] */
# define LPSPI_TCR_PCS_5 (0x05 << LPSPI_TCR_PCS_SHIFT) /* Transfer using PCS[5] */
# define LPSPI_TCR_PCS_6 (0x06 << LPSPI_TCR_PCS_SHIFT) /* Transfer using PCS[6] */
# define LPSPI_TCR_PCS_7 (0x07 << LPSPI_TCR_PCS_SHIFT) /* Transfer using PCS[7] */
#define LPSPI_TCR_PRESCALE_SHIFT (27) /* Bits 27-29: Prescaler Value (PRESCALE) */
#define LPSPI_TCR_PRESCALE_MASK (0x07 << LPSPI_TCR_PRESCALE_SHIFT)
# define LPSPI_TCR_PRESCALE_DIV1 (0x00 << LPSPI_TCR_PRESCALE_SHIFT) /* Divide by 1 */
# define LPSPI_TCR_PRESCALE_DIV2 (0x01 << LPSPI_TCR_PRESCALE_SHIFT) /* Divide by 2 */
# define LPSPI_TCR_PRESCALE_DIV4 (0x02 << LPSPI_TCR_PRESCALE_SHIFT) /* Divide by 4 */
# define LPSPI_TCR_PRESCALE_DIV8 (0x03 << LPSPI_TCR_PRESCALE_SHIFT) /* Divide by 8 */
# define LPSPI_TCR_PRESCALE_DIV16 (0x04 << LPSPI_TCR_PRESCALE_SHIFT) /* Divide by 16 */
# define LPSPI_TCR_PRESCALE_DIV32 (0x05 << LPSPI_TCR_PRESCALE_SHIFT) /* Divide by 32 */
# define LPSPI_TCR_PRESCALE_DIV64 (0x06 << LPSPI_TCR_PRESCALE_SHIFT) /* Divide by 64 */
# define LPSPI_TCR_PRESCALE_DIV128 (0x07 << LPSPI_TCR_PRESCALE_SHIFT) /* Divide by 128 */
# define LPSPI_TCR_PRESCALE(n) ((n) << LPSPI_TCR_PRESCALE_SHIFT)
#define LPSPI_TCR_CPHA (1 << 30) /* Bit 30: Clock Phase (CPHA) */
# define LPSPI_TCR_CPHA_CAPTURED (0 << 30) /* Data is captured on the leading edge of SCK and changed on the following edge of SCK */
# define LPSPI_TCR_CPHA_CHANGED (1 << 30) /* Data is changed on the leading edge of SCK and captured on the following edge of SCK */
#define LPSPI_TCR_CPOL (1 << 31) /* Bit 31: Clock Polarity (CPOL) */
# define LPSPI_TCR_CPOL_LOW (0 << 31) /* The inactive state value of SCK is low */
# define LPSPI_TCR_CPOL_HIGH (1 << 31) /* The inactive state value of SCK is high */
/* Transmit Data Register (TDR) */
#define LPSPI_TDR_DATA_SHIFT (0) /* Bits 0-31: Transmit Data (DATA) */
#define LPSPI_TDR_DATA_MASK (0xffffffff << LPSPI_TDR_DATA_SHIFT)
/* Receive Status Register (RSR) */
#define LPSPI_RSR_SOF (1 << 0) /* Bit 0: Start Of Frame (SOF) */
#define LPSPI_RSR_RXEMPTY (1 << 1) /* Bit 1: RX FIFO Empty (RXEMPTY) */
/* Bits 2-31: Reserved */
/* Receive Data Register (RDR) */
#define LPSPI_RDR_DATA_SHIFT (0) /* Bits 0-31: Receive Data (DATA) */
#define LPSPI_RDR_DATA_MASK (0xffffffff << LPSPI_RDR_DATA_SHIFT)
/* Receive Data Read Only Register (RDROR) */
#define LPSPI_RDROR_DATA_SHIFT (0) /* Bits 0-31: Receive Data (DATA) */
#define LPSPI_RDROR_DATA_MASK (0xffffffff << LPSPI_RDROR_DATA_SHIFT)
/* Transmit Command Burst Register (TCBR) */
#define LPSPI_TCBR_DATA_SHIFT (0) /* Bits 0-31: Command Data (DATA) */
#define LPSPI_TCBR_DATA_MASK (0xffffffff << LPSPI_TCBR_DATA_SHIFT)
/* Transmit Data Burst Register (TDBR) */
#define LPSPI_TDBR_DATA_SHIFT (0) /* Bits 0-31: Data (DATA) */
#define LPSPI_TDBR_DATA_MASK (0xffffffff << LPSPI_TDBR_DATA_SHIFT)
/* Receive Data Burst Register (RDBR) */
#define LPSPI_RDBR_DATA_SHIFT (0) /* Bits 0-31: Data (DATA) */
#define LPSPI_RDBR_DATA_MASK (0xffffffff << LPSPI_RDBR_DATA_SHIFT)
#endif /* __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_LPSPI_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,139 @@
/****************************************************************************
* arch/arm64/src/imx9/imx9_lpspi.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM64_SRC_IMX9_IMX9_LPSPI_H
#define __ARCH_ARM64_SRC_IMX9_IMX9_LPSPI_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <nuttx/spi/spi.h>
#include "chip.h"
#include "hardware/imx9_lpspi.h"
/****************************************************************************
* Public Functions Prototypes
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
struct spi_dev_s; /* Forward reference */
/****************************************************************************
* Name: imx9_lpspibus_initialize
*
* Description:
* Initialize the selected SPI bus
*
* Input Parameters:
* bus number (for hardware that has multiple SPI interfaces)
*
* Returned Value:
* Valid SPI device structure reference on success; a NULL on failure
*
****************************************************************************/
struct spi_dev_s *imx9_lpspibus_initialize(int bus);
/****************************************************************************
* Name: imx9_lpspi1/2/...select and imx9_lpspi1/2/...status
*
* Description:
* The external functions, imx9_lpspi1/2/...select,
* imx9_lpspi1/2/...status, and imx9_lpspi1/2/...cmddata must be
* provided by board-specific logic. These are implementations of the
* select, status, and cmddata methods of the SPI interface defined by
* struct spi_ops_s (see include/nuttx/spi/spi.h). All other methods
* (including imx9_lpspibus_initialize()) are provided by common IMX9
* logic. To use this common SPI logic on your board:
*
* 1. Provide logic in imx9_boardinitialize() to configure SPI chip select
* pins.
* 2. Provide imx9_lpspi1/2/...select() and imx9_lpspi1/2/...status()
* functions in your board-specific logic. These functions will perform
* chip selection and status operations using GPIOs in the way your
* board is configured.
* 3. If CONFIG_SPI_CMDDATA is defined in your NuttX configuration file,
* then provide imx9_lpspi1/2/...cmddata() functions in your
* board-specific logic. These functions will perform cmd/data selection
* operations using GPIOs in the way your board is configured.
* 4. Add a calls to imx9_lpspibus_initialize() in your low level
* application initialization logic
* 5. The handle returned by imx9_lpspibus_initialize() may then be used
* to bind the SPI driver to higher level logic (e.g., calling
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to
* the SPI MMC/SD driver).
*
****************************************************************************/
void imx9_lpspi_select(struct spi_dev_s *dev,
uint32_t devid, bool selected);
uint8_t imx9_lpspi_status(struct spi_dev_s *dev, uint32_t devid);
int imx9_lpspi_cmddata(struct spi_dev_s *dev,
uint32_t devid, bool cmd);
/****************************************************************************
* Name: imx9_lpspi1/2/...register
*
* Description:
* If the board supports a card detect callback to inform the SPI-based
* MMC/SD driver when an SD card is inserted or removed, then
* CONFIG_SPI_CALLBACK should be defined and the following function(s)
* must be implemented. These functions implements the registercallback
* method of the SPI interface (see include/nuttx/spi/spi.h for details)
*
* Input Parameters:
* dev - Device-specific state data
* callback - The function to call on the media change
* arg - A caller provided value to return with the callback
*
* Returned Value:
* 0 on success; negated errno on failure.
*
****************************************************************************/
#ifdef CONFIG_SPI_CALLBACK
int imx9_lpspi_register(struct spi_dev_s *dev,
spi_mediachange_t callback,
void *arg);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM64_SRC_IMX9_IMX9_LPSPI_H */

View File

@ -36,6 +36,7 @@ CONFIG_IMX9_GPIO_IRQ=y
CONFIG_IMX9_LPI2C1=y
CONFIG_IMX9_LPI2C_DYNTIMEO=y
CONFIG_IMX9_LPI2C_DYNTIMEO_STARTSTOP=10
CONFIG_IMX9_LPSPI6=y
CONFIG_IMX9_LPUART1=y
CONFIG_IMX9_TPM3_PWM=y
CONFIG_IMX9_TPM3_PWM_CHMUX=0x00000003
@ -60,6 +61,7 @@ CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_HPWORKPRIORITY=192
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_LPWORKPRIORITY=50
CONFIG_SPI=y
CONFIG_SPINLOCK=y
CONFIG_STACK_COLORATION=y
CONFIG_START_MONTH=3
@ -68,6 +70,7 @@ CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_CDCACM=y
CONFIG_SYSTEM_I2CTOOL=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SPITOOL=y
CONFIG_SYSTEM_SYSTEM=y
CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y

View File

@ -31,7 +31,11 @@
* Pre-processor Definitions
****************************************************************************/
/* Default PAD configurations */
#define IOMUX_LPI2C_DEFAULT (IOMUXC_PAD_OD_ENABLE | IOMUXC_PAD_FSEL_SFAST | IOMUXC_PAD_DSE_X6)
#define IOMUX_LPSPI_DEFAULT (IOMUXC_PAD_PU_ON | IOMUXC_PAD_FSEL_FAST | IOMUXC_PAD_DSE_X6)
#define IOMUX_GPIO_DEFAULT (IOMUXC_PAD_FSEL_SLOW | IOMUXC_PAD_DSE_X6)
/* UART pin muxings */
@ -68,6 +72,22 @@
#define GPIO_LPI2C1_SCL_RESET (GPIO_PORT1 | GPIO_PIN0 | GPIO_OUTPUT | GPIO_OUTPUT_ONE)
#define GPIO_LPI2C1_SDA_RESET (GPIO_PORT1 | GPIO_PIN1 | GPIO_OUTPUT | GPIO_OUTPUT_ONE)
/* LPSPIs */
#define MUX_LPSPI3_SCK IOMUX_CFG(IOMUXC_PAD_GPIO_IO11_LPSPI3_SCK, IOMUX_LPSPI_DEFAULT, IOMUXC_MUX_SION_ON)
#define MUX_LPSPI3_MOSI IOMUX_CFG(IOMUXC_PAD_GPIO_IO10_LPSPI3_SOUT, IOMUX_LPSPI_DEFAULT, IOMUXC_MUX_SION_ON)
#define MUX_LPSPI3_MISO IOMUX_CFG(IOMUXC_PAD_GPIO_IO09_LPSPI3_SIN, IOMUX_LPSPI_DEFAULT, IOMUXC_MUX_SION_ON)
#define MUX_LPSPI6_SCK IOMUX_CFG(IOMUXC_PAD_GPIO_IO03_LPSPI6_SCK, IOMUX_LPSPI_DEFAULT, IOMUXC_MUX_SION_ON)
#define MUX_LPSPI6_MOSI IOMUX_CFG(IOMUXC_PAD_GPIO_IO02_LPSPI6_SOUT, IOMUX_LPSPI_DEFAULT, IOMUXC_MUX_SION_ON)
#define MUX_LPSPI6_MISO IOMUX_CFG(IOMUXC_PAD_GPIO_IO01_LPSPI6_SIN, IOMUX_LPSPI_DEFAULT, IOMUXC_MUX_SION_ON)
/* SPI CS */
#define MUX_LPSPI3_CS IOMUX_CFG(IOMUXC_PAD_GPIO_IO08_GPIO2_IO08, IOMUX_GPIO_DEFAULT, IOMUXC_MUX_SION_ON)
#define GPIO_LPSPI3_CS (GPIO_PORT2 | GPIO_PIN8 | GPIO_OUTPUT | GPIO_OUTPUT_ONE)
#define MUX_LPSPI6_CS IOMUX_CFG(IOMUXC_PAD_GPIO_IO00_GPIO2_IO00, IOMUX_GPIO_DEFAULT, IOMUXC_MUX_SION_ON)
#define GPIO_LPSPI6_CS (GPIO_PORT2 | GPIO_PIN0 | GPIO_OUTPUT | GPIO_OUTPUT_ONE)
/****************************************************************************
* Public Data
****************************************************************************/

View File

@ -34,4 +34,8 @@ ifeq ($(CONFIG_IMX9_LPI2C),y)
CSRCS += imx9_i2c.c
endif
ifeq ($(CONFIG_IMX9_LPSPI),y)
CSRCS += imx9_spi.c
endif
include $(TOPDIR)/boards/Board.mk

View File

@ -79,5 +79,17 @@ int imx9_pwm_setup(void);
int imx9_i2c_initialize(void);
#endif
/****************************************************************************
* Name: imx9_spi_setup
*
* Description:
* Initialize SPI devices and driver
*
****************************************************************************/
#if defined(CONFIG_SPI_DRIVER)
int imx9_spi_initialize(void);
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM64_IMX9_IMX93_EVK_SRC_IMX93_EVK_H */

View File

@ -77,6 +77,16 @@ int imx9_bringup(void)
}
#endif
#if defined(CONFIG_SPI_DRIVER)
/* Configure SPI peripheral interfaces */
ret = imx9_spi_initialize();
if (ret < 0)
{
syslog(LOG_ERR, "Failed to initialize SPI driver: %d\n", ret);
}
#endif
UNUSED(ret);
return OK;
}

View File

@ -0,0 +1,162 @@
/****************************************************************************
* boards/arm64/imx9/imx93-evk/src/imx9_spi.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <errno.h>
#include <sys/types.h>
#include <nuttx/spi/spi_transfer.h>
#include <arch/board/board.h>
#include "imx9_gpio.h"
#include "imx9_lpspi.h"
/****************************************************************************
* Private Data
****************************************************************************/
#ifdef CONFIG_IMX9_LPSPI6
static struct spi_dev_s *g_spi6;
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#ifdef CONFIG_IMX9_LPSPI
/****************************************************************************
* Name: imx9_lpspix_select
*
* Description:
* Enable/disable the SPI chip select. The implementation of this method
* must include handshaking: If a device is selected, it must hold off
* all other attempts to select the device until the device is deselected.
* Required.
*
* Input Parameters:
* dev - Device-specific state data
* devid - Identifies the device to select
* selected - true: slave selected, false: slave de-selected
*
* Returned Value:
* None
*
****************************************************************************/
void imx9_lpspi_select(struct spi_dev_s *dev, uint32_t devid, bool selected)
{
#ifdef CONFIG_IMX9_LPSPI6
if (dev == g_spi6)
{
imx9_gpio_write(GPIO_LPSPI6_CS, !selected);
}
#endif
}
/****************************************************************************
* Name: imx9_lpspix_status
*
* Description:
* Get SPI/MMC status. Optional.
*
* Input Parameters:
* dev - Device-specific state data
* devid - Identifies the device to report status on
*
* Returned Value:
* Returns a bitset of status values (see SPI_STATUS_* defines)
*
****************************************************************************/
uint8_t imx9_lpspi_status(struct spi_dev_s *dev, uint32_t devid)
{
return 0;
}
/****************************************************************************
* Name: imx9_lpspixcmddata
*
* Description:
* Some devices require an additional out-of-band bit to specify if the
* next word sent to the device is a command or data. This is typical, for
* example, in "9-bit" displays where the 9th bit is the CMD/DATA bit.
* This function provides selection of command or data.
*
* This "latches" the CMD/DATA state. It does not have to be called before
* every word is transferred; only when the CMD/DATA state changes. This
* method is required if CONFIG_SPI_CMDDATA is selected in the NuttX
* configuration
*
* Input Parameters:
* dev - Device-specific state data
* cmd - TRUE: The following word is a command; FALSE: the following words
* are data.
*
* Returned Value:
* OK unless an error occurs. Then a negated errno value is returned
*
****************************************************************************/
int imx9_lpspi_cmddata(struct spi_dev_s *dev, uint32_t devid, bool cmd)
{
return -ENODEV;
}
#endif
/****************************************************************************
* Name: board_spi_initialize
*
* Description:
* Initialize and register SPI driver for the defined SPI ports.
*
****************************************************************************/
int imx9_spi_initialize(void)
{
int ret = OK;
#if defined(CONFIG_IMX9_LPSPI)
/* Initialize SPI device */
g_spi6 = imx9_lpspibus_initialize(6);
if (g_spi6 == NULL)
{
spierr("Failed to initialize SPI6\n");
return -ENODEV;
}
#endif /* CONFIG_MPFS_SPI0 */
#ifdef CONFIG_SPI_DRIVER
ret = spi_register(g_spi6, 0);
if (ret < 0)
{
spierr("Failed to register /dev/spi0: %d\n", ret);
}
#endif /* CONFIG_SPI_DRIVER */
return OK;
}