Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 00505edf authored by Cezary Gapinski's avatar Cezary Gapinski Committed by Mark Brown
Browse files

spi: stm32: add support for STM32F4



Add routines, registers & bitfield definition. Also baud rate divisor
definitions for STM32F4 SPI. This version supports full-duplex,
simplex TX and half-duplex TX communication with 8 or 16-bit per word.
DMA capability is optionally supported for transfer longer than 16 bytes.
For transfer less than 16 bytes frames can be send in discontinuous mode.

Signed-off-by: default avatarCezary Gapinski <cezary.gapinski@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 55166853
Loading
Loading
Loading
Loading
+482 −7
Original line number Original line Diff line number Diff line
@@ -20,6 +20,59 @@


#define DRIVER_NAME "spi_stm32"
#define DRIVER_NAME "spi_stm32"


/* STM32F4 SPI registers */
#define STM32F4_SPI_CR1			0x00
#define STM32F4_SPI_CR2			0x04
#define STM32F4_SPI_SR			0x08
#define STM32F4_SPI_DR			0x0C
#define STM32F4_SPI_I2SCFGR		0x1C

/* STM32F4_SPI_CR1 bit fields */
#define STM32F4_SPI_CR1_CPHA		BIT(0)
#define STM32F4_SPI_CR1_CPOL		BIT(1)
#define STM32F4_SPI_CR1_MSTR		BIT(2)
#define STM32F4_SPI_CR1_BR_SHIFT	3
#define STM32F4_SPI_CR1_BR		GENMASK(5, 3)
#define STM32F4_SPI_CR1_SPE		BIT(6)
#define STM32F4_SPI_CR1_LSBFRST		BIT(7)
#define STM32F4_SPI_CR1_SSI		BIT(8)
#define STM32F4_SPI_CR1_SSM		BIT(9)
#define STM32F4_SPI_CR1_RXONLY		BIT(10)
#define STM32F4_SPI_CR1_DFF		BIT(11)
#define STM32F4_SPI_CR1_CRCNEXT		BIT(12)
#define STM32F4_SPI_CR1_CRCEN		BIT(13)
#define STM32F4_SPI_CR1_BIDIOE		BIT(14)
#define STM32F4_SPI_CR1_BIDIMODE	BIT(15)
#define STM32F4_SPI_CR1_BR_MIN		0
#define STM32F4_SPI_CR1_BR_MAX		(GENMASK(5, 3) >> 3)

/* STM32F4_SPI_CR2 bit fields */
#define STM32F4_SPI_CR2_RXDMAEN		BIT(0)
#define STM32F4_SPI_CR2_TXDMAEN		BIT(1)
#define STM32F4_SPI_CR2_SSOE		BIT(2)
#define STM32F4_SPI_CR2_FRF		BIT(4)
#define STM32F4_SPI_CR2_ERRIE		BIT(5)
#define STM32F4_SPI_CR2_RXNEIE		BIT(6)
#define STM32F4_SPI_CR2_TXEIE		BIT(7)

/* STM32F4_SPI_SR bit fields */
#define STM32F4_SPI_SR_RXNE		BIT(0)
#define STM32F4_SPI_SR_TXE		BIT(1)
#define STM32F4_SPI_SR_CHSIDE		BIT(2)
#define STM32F4_SPI_SR_UDR		BIT(3)
#define STM32F4_SPI_SR_CRCERR		BIT(4)
#define STM32F4_SPI_SR_MODF		BIT(5)
#define STM32F4_SPI_SR_OVR		BIT(6)
#define STM32F4_SPI_SR_BSY		BIT(7)
#define STM32F4_SPI_SR_FRE		BIT(8)

/* STM32F4_SPI_I2SCFGR bit fields */
#define STM32F4_SPI_I2SCFGR_I2SMOD	BIT(11)

/* STM32F4 SPI Baud Rate min/max divisor */
#define STM32F4_SPI_BR_DIV_MIN		(2 << STM32F4_SPI_CR1_BR_MIN)
#define STM32F4_SPI_BR_DIV_MAX		(2 << STM32F4_SPI_CR1_BR_MAX)

/* STM32H7 SPI registers */
/* STM32H7 SPI registers */
#define STM32H7_SPI_CR1			0x00
#define STM32H7_SPI_CR1			0x00
#define STM32H7_SPI_CR2			0x04
#define STM32H7_SPI_CR2			0x04
@@ -116,6 +169,12 @@


#define SPI_1HZ_NS		1000000000
#define SPI_1HZ_NS		1000000000


/*
 * use PIO for small transfers, avoiding DMA setup/teardown overhead for drivers
 * without fifo buffers.
 */
#define SPI_DMA_MIN_BYTES	16

/**
/**
 * stm32_spi_reg - stm32 SPI register & bitfield desc
 * stm32_spi_reg - stm32 SPI register & bitfield desc
 * @reg:		register offset
 * @reg:		register offset
@@ -257,6 +316,21 @@ struct stm32_spi {
	dma_addr_t phys_addr;
	dma_addr_t phys_addr;
};
};


static const struct stm32_spi_regspec stm32f4_spi_regspec = {
	.en = { STM32F4_SPI_CR1, STM32F4_SPI_CR1_SPE },

	.dma_rx_en = { STM32F4_SPI_CR2, STM32F4_SPI_CR2_RXDMAEN },
	.dma_tx_en = { STM32F4_SPI_CR2, STM32F4_SPI_CR2_TXDMAEN },

	.cpol = { STM32F4_SPI_CR1, STM32F4_SPI_CR1_CPOL },
	.cpha = { STM32F4_SPI_CR1, STM32F4_SPI_CR1_CPHA },
	.lsb_first = { STM32F4_SPI_CR1, STM32F4_SPI_CR1_LSBFRST },
	.br = { STM32F4_SPI_CR1, STM32F4_SPI_CR1_BR, STM32F4_SPI_CR1_BR_SHIFT },

	.rx = { STM32F4_SPI_DR },
	.tx = { STM32F4_SPI_DR },
};

static const struct stm32_spi_regspec stm32h7_spi_regspec = {
static const struct stm32_spi_regspec stm32h7_spi_regspec = {
	/* SPI data transfer is enabled but spi_ker_ck is idle.
	/* SPI data transfer is enabled but spi_ker_ck is idle.
	 * CFG1 and CFG2 registers are write protected when SPE is enabled.
	 * CFG1 and CFG2 registers are write protected when SPE is enabled.
@@ -315,6 +389,16 @@ static int stm32h7_spi_get_fifo_size(struct stm32_spi *spi)
	return count;
	return count;
}
}


/**
 * stm32f4_spi_get_bpw_mask - Return bits per word mask
 * @spi: pointer to the spi controller data structure
 */
static int stm32f4_spi_get_bpw_mask(struct stm32_spi *spi)
{
	dev_dbg(spi->dev, "8-bit or 16-bit data frame supported\n");
	return SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
}

/**
/**
 * stm32h7_spi_get_bpw_mask - Return bits per word mask
 * stm32h7_spi_get_bpw_mask - Return bits per word mask
 * @spi: pointer to the spi controller data structure
 * @spi: pointer to the spi controller data structure
@@ -408,6 +492,35 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi)
	return fthlv;
	return fthlv;
}
}


/**
 * stm32f4_spi_write_tx - Write bytes to Transmit Data Register
 * @spi: pointer to the spi controller data structure
 *
 * Read from tx_buf depends on remaining bytes to avoid to read beyond
 * tx_buf end.
 */
static void stm32f4_spi_write_tx(struct stm32_spi *spi)
{
	if ((spi->tx_len > 0) && (readl_relaxed(spi->base + STM32F4_SPI_SR) &
				  STM32F4_SPI_SR_TXE)) {
		u32 offs = spi->cur_xferlen - spi->tx_len;

		if (spi->cur_bpw == 16) {
			const u16 *tx_buf16 = (const u16 *)(spi->tx_buf + offs);

			writew_relaxed(*tx_buf16, spi->base + STM32F4_SPI_DR);
			spi->tx_len -= sizeof(u16);
		} else {
			const u8 *tx_buf8 = (const u8 *)(spi->tx_buf + offs);

			writeb_relaxed(*tx_buf8, spi->base + STM32F4_SPI_DR);
			spi->tx_len -= sizeof(u8);
		}
	}

	dev_dbg(spi->dev, "%s: %d bytes left\n", __func__, spi->tx_len);
}

/**
/**
 * stm32h7_spi_write_txfifo - Write bytes in Transmit Data Register
 * stm32h7_spi_write_txfifo - Write bytes in Transmit Data Register
 * @spi: pointer to the spi controller data structure
 * @spi: pointer to the spi controller data structure
@@ -443,6 +556,35 @@ static void stm32h7_spi_write_txfifo(struct stm32_spi *spi)
	dev_dbg(spi->dev, "%s: %d bytes left\n", __func__, spi->tx_len);
	dev_dbg(spi->dev, "%s: %d bytes left\n", __func__, spi->tx_len);
}
}


/**
 * stm32f4_spi_read_rx - Read bytes from Receive Data Register
 * @spi: pointer to the spi controller data structure
 *
 * Write in rx_buf depends on remaining bytes to avoid to write beyond
 * rx_buf end.
 */
static void stm32f4_spi_read_rx(struct stm32_spi *spi)
{
	if ((spi->rx_len > 0) && (readl_relaxed(spi->base + STM32F4_SPI_SR) &
				  STM32F4_SPI_SR_RXNE)) {
		u32 offs = spi->cur_xferlen - spi->rx_len;

		if (spi->cur_bpw == 16) {
			u16 *rx_buf16 = (u16 *)(spi->rx_buf + offs);

			*rx_buf16 = readw_relaxed(spi->base + STM32F4_SPI_DR);
			spi->rx_len -= sizeof(u16);
		} else {
			u8 *rx_buf8 = (u8 *)(spi->rx_buf + offs);

			*rx_buf8 = readb_relaxed(spi->base + STM32F4_SPI_DR);
			spi->rx_len -= sizeof(u8);
		}
	}

	dev_dbg(spi->dev, "%s: %d bytes left\n", __func__, spi->rx_len);
}

/**
/**
 * stm32h7_spi_read_rxfifo - Read bytes in Receive Data Register
 * stm32h7_spi_read_rxfifo - Read bytes in Receive Data Register
 * @spi: pointer to the spi controller data structure
 * @spi: pointer to the spi controller data structure
@@ -501,6 +643,54 @@ static void stm32_spi_enable(struct stm32_spi *spi)
			   spi->cfg->regs->en.mask);
			   spi->cfg->regs->en.mask);
}
}


/**
 * stm32f4_spi_disable - Disable SPI controller
 * @spi: pointer to the spi controller data structure
 */
static void stm32f4_spi_disable(struct stm32_spi *spi)
{
	unsigned long flags;
	u32 sr;

	dev_dbg(spi->dev, "disable controller\n");

	spin_lock_irqsave(&spi->lock, flags);

	if (!(readl_relaxed(spi->base + STM32F4_SPI_CR1) &
	      STM32F4_SPI_CR1_SPE)) {
		spin_unlock_irqrestore(&spi->lock, flags);
		return;
	}

	/* Disable interrupts */
	stm32_spi_clr_bits(spi, STM32F4_SPI_CR2, STM32F4_SPI_CR2_TXEIE |
						 STM32F4_SPI_CR2_RXNEIE |
						 STM32F4_SPI_CR2_ERRIE);

	/* Wait until BSY = 0 */
	if (readl_relaxed_poll_timeout_atomic(spi->base + STM32F4_SPI_SR,
					      sr, !(sr & STM32F4_SPI_SR_BSY),
					      10, 100000) < 0) {
		dev_warn(spi->dev, "disabling condition timeout\n");
	}

	if (spi->cur_usedma && spi->dma_tx)
		dmaengine_terminate_all(spi->dma_tx);
	if (spi->cur_usedma && spi->dma_rx)
		dmaengine_terminate_all(spi->dma_rx);

	stm32_spi_clr_bits(spi, STM32F4_SPI_CR1, STM32F4_SPI_CR1_SPE);

	stm32_spi_clr_bits(spi, STM32F4_SPI_CR2, STM32F4_SPI_CR2_TXDMAEN |
						 STM32F4_SPI_CR2_RXDMAEN);

	/* Sequence to clear OVR flag */
	readl_relaxed(spi->base + STM32F4_SPI_DR);
	readl_relaxed(spi->base + STM32F4_SPI_SR);

	spin_unlock_irqrestore(&spi->lock, flags);
}

/**
/**
 * stm32h7_spi_disable - Disable SPI controller
 * stm32h7_spi_disable - Disable SPI controller
 * @spi: pointer to the spi controller data structure
 * @spi: pointer to the spi controller data structure
@@ -568,18 +758,128 @@ static void stm32h7_spi_disable(struct stm32_spi *spi)
/**
/**
 * stm32_spi_can_dma - Determine if the transfer is eligible for DMA use
 * stm32_spi_can_dma - Determine if the transfer is eligible for DMA use
 *
 *
 * If the current transfer size is greater than fifo size, use DMA.
 * If driver has fifo and the current transfer size is greater than fifo size,
 * use DMA. Otherwise use DMA for transfer longer than defined DMA min bytes.
 */
 */
static bool stm32_spi_can_dma(struct spi_master *master,
static bool stm32_spi_can_dma(struct spi_master *master,
			      struct spi_device *spi_dev,
			      struct spi_device *spi_dev,
			      struct spi_transfer *transfer)
			      struct spi_transfer *transfer)
{
{
	unsigned int dma_size;
	struct stm32_spi *spi = spi_master_get_devdata(master);
	struct stm32_spi *spi = spi_master_get_devdata(master);


	if (spi->cfg->has_fifo)
		dma_size = spi->fifo_size;
	else
		dma_size = SPI_DMA_MIN_BYTES;

	dev_dbg(spi->dev, "%s: %s\n", __func__,
	dev_dbg(spi->dev, "%s: %s\n", __func__,
		(transfer->len > spi->fifo_size) ? "true" : "false");
		(transfer->len > dma_size) ? "true" : "false");

	return (transfer->len > dma_size);
}

/**
 * stm32f4_spi_irq_event - Interrupt handler for SPI controller events
 * @irq: interrupt line
 * @dev_id: SPI controller master interface
 */
static irqreturn_t stm32f4_spi_irq_event(int irq, void *dev_id)
{
	struct spi_master *master = dev_id;
	struct stm32_spi *spi = spi_master_get_devdata(master);
	u32 sr, mask = 0;
	unsigned long flags;
	bool end = false;

	spin_lock_irqsave(&spi->lock, flags);

	sr = readl_relaxed(spi->base + STM32F4_SPI_SR);
	/*
	 * BSY flag is not handled in interrupt but it is normal behavior when
	 * this flag is set.
	 */
	sr &= ~STM32F4_SPI_SR_BSY;

	if (!spi->cur_usedma && (spi->cur_comm == SPI_SIMPLEX_TX ||
				 spi->cur_comm == SPI_3WIRE_TX)) {
		/* OVR flag shouldn't be handled for TX only mode */
		sr &= ~STM32F4_SPI_SR_OVR | STM32F4_SPI_SR_RXNE;
		mask |= STM32F4_SPI_SR_TXE;
	}

	if (!spi->cur_usedma && spi->cur_comm == SPI_FULL_DUPLEX) {
		/* TXE flag is set and is handled when RXNE flag occurs */
		sr &= ~STM32F4_SPI_SR_TXE;
		mask |= STM32F4_SPI_SR_RXNE | STM32F4_SPI_SR_OVR;
	}

	if (!(sr & mask)) {
		dev_dbg(spi->dev, "spurious IT (sr=0x%08x)\n", sr);
		spin_unlock_irqrestore(&spi->lock, flags);
		return IRQ_NONE;
	}

	if (sr & STM32F4_SPI_SR_OVR) {
		dev_warn(spi->dev, "Overrun: received value discarded\n");

		/* Sequence to clear OVR flag */
		readl_relaxed(spi->base + STM32F4_SPI_DR);
		readl_relaxed(spi->base + STM32F4_SPI_SR);

		/*
		 * If overrun is detected, it means that something went wrong,
		 * so stop the current transfer. Transfer can wait for next
		 * RXNE but DR is already read and end never happens.
		 */
		end = true;
		goto end_irq;
	}

	if (sr & STM32F4_SPI_SR_TXE) {
		if (spi->tx_buf)
			stm32f4_spi_write_tx(spi);
		if (spi->tx_len == 0)
			end = true;
	}

	if (sr & STM32F4_SPI_SR_RXNE) {
		stm32f4_spi_read_rx(spi);
		if (spi->rx_len == 0)
			end = true;
		else /* Load data for discontinuous mode */
			stm32f4_spi_write_tx(spi);
	}

end_irq:
	if (end) {
		/* Immediately disable interrupts to do not generate new one */
		stm32_spi_clr_bits(spi, STM32F4_SPI_CR2,
					STM32F4_SPI_CR2_TXEIE |
					STM32F4_SPI_CR2_RXNEIE |
					STM32F4_SPI_CR2_ERRIE);
		spin_unlock_irqrestore(&spi->lock, flags);
		return IRQ_WAKE_THREAD;
	}

	spin_unlock_irqrestore(&spi->lock, flags);
	return IRQ_HANDLED;
}

/**
 * stm32f4_spi_irq_thread - Thread of interrupt handler for SPI controller
 * @irq: interrupt line
 * @dev_id: SPI controller master interface
 */
static irqreturn_t stm32f4_spi_irq_thread(int irq, void *dev_id)
{
	struct spi_master *master = dev_id;
	struct stm32_spi *spi = spi_master_get_devdata(master);

	spi_finalize_current_transfer(master);
	stm32f4_spi_disable(spi);


	return (transfer->len > spi->fifo_size);
	return IRQ_HANDLED;
}
}


/**
/**
@@ -748,6 +1048,34 @@ static int stm32_spi_prepare_msg(struct spi_master *master,
	return 0;
	return 0;
}
}


/**
 * stm32f4_spi_dma_tx_cb - dma callback
 *
 * DMA callback is called when the transfer is complete for DMA TX channel.
 */
static void stm32f4_spi_dma_tx_cb(void *data)
{
	struct stm32_spi *spi = data;

	if (spi->cur_comm == SPI_SIMPLEX_TX || spi->cur_comm == SPI_3WIRE_TX) {
		spi_finalize_current_transfer(spi->master);
		stm32f4_spi_disable(spi);
	}
}

/**
 * stm32f4_spi_dma_rx_cb - dma callback
 *
 * DMA callback is called when the transfer is complete for DMA RX channel.
 */
static void stm32f4_spi_dma_rx_cb(void *data)
{
	struct stm32_spi *spi = data;

	spi_finalize_current_transfer(spi->master);
	stm32f4_spi_disable(spi);
}

/**
/**
 * stm32h7_spi_dma_cb - dma callback
 * stm32h7_spi_dma_cb - dma callback
 *
 *
@@ -790,11 +1118,15 @@ static void stm32_spi_dma_config(struct stm32_spi *spi,
	else
	else
		buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
		buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;


	if (spi->cfg->has_fifo) {
		/* Valid for DMA Half or Full Fifo threshold */
		/* Valid for DMA Half or Full Fifo threshold */
		if (spi->cur_fthlv == 2)
		if (spi->cur_fthlv == 2)
			maxburst = 1;
			maxburst = 1;
		else
		else
			maxburst = spi->cur_fthlv;
			maxburst = spi->cur_fthlv;
	} else {
		maxburst = 1;
	}


	memset(dma_conf, 0, sizeof(struct dma_slave_config));
	memset(dma_conf, 0, sizeof(struct dma_slave_config));
	dma_conf->direction = dir;
	dma_conf->direction = dir;
@@ -815,6 +1147,46 @@ static void stm32_spi_dma_config(struct stm32_spi *spi,
	}
	}
}
}


/**
 * stm32f4_spi_transfer_one_irq - transfer a single spi_transfer using
 *				  interrupts
 *
 * It must returns 0 if the transfer is finished or 1 if the transfer is still
 * in progress.
 */
static int stm32f4_spi_transfer_one_irq(struct stm32_spi *spi)
{
	unsigned long flags;
	u32 cr2 = 0;

	/* Enable the interrupts relative to the current communication mode */
	if (spi->cur_comm == SPI_SIMPLEX_TX || spi->cur_comm == SPI_3WIRE_TX) {
		cr2 |= STM32F4_SPI_CR2_TXEIE;
	} else if (spi->cur_comm == SPI_FULL_DUPLEX) {
		/* In transmit-only mode, the OVR flag is set in the SR register
		 * since the received data are never read. Therefore set OVR
		 * interrupt only when rx buffer is available.
		 */
		cr2 |= STM32F4_SPI_CR2_RXNEIE | STM32F4_SPI_CR2_ERRIE;
	} else {
		return -EINVAL;
	}

	spin_lock_irqsave(&spi->lock, flags);

	stm32_spi_set_bits(spi, STM32F4_SPI_CR2, cr2);

	stm32_spi_enable(spi);

	/* starting data transfer when buffer is loaded */
	if (spi->tx_buf)
		stm32f4_spi_write_tx(spi);

	spin_unlock_irqrestore(&spi->lock, flags);

	return 1;
}

/**
/**
 * stm32h7_spi_transfer_one_irq - transfer a single spi_transfer using
 * stm32h7_spi_transfer_one_irq - transfer a single spi_transfer using
 *				  interrupts
 *				  interrupts
@@ -856,6 +1228,26 @@ static int stm32h7_spi_transfer_one_irq(struct stm32_spi *spi)
	return 1;
	return 1;
}
}


/**
 * stm32f4_spi_transfer_one_dma_start - Set SPI driver registers to start
 *					transfer using DMA
 */
static void stm32f4_spi_transfer_one_dma_start(struct stm32_spi *spi)
{
	/* In DMA mode end of transfer is handled by DMA TX or RX callback. */
	if (spi->cur_comm == SPI_SIMPLEX_RX || spi->cur_comm == SPI_3WIRE_RX ||
	    spi->cur_comm == SPI_FULL_DUPLEX) {
		/*
		 * In transmit-only mode, the OVR flag is set in the SR register
		 * since the received data are never read. Therefore set OVR
		 * interrupt only when rx buffer is available.
		 */
		stm32_spi_set_bits(spi, STM32F4_SPI_CR2, STM32F4_SPI_CR2_ERRIE);
	}

	stm32_spi_enable(spi);
}

/**
/**
 * stm32h7_spi_transfer_one_dma_start - Set SPI driver registers to start
 * stm32h7_spi_transfer_one_dma_start - Set SPI driver registers to start
 *					transfer using DMA
 *					transfer using DMA
@@ -976,6 +1368,18 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi,
	return spi->cfg->transfer_one_irq(spi);
	return spi->cfg->transfer_one_irq(spi);
}
}


/**
 * stm32f4_spi_set_bpw - Configure bits per word
 * @spi: pointer to the spi controller data structure
 */
static void stm32f4_spi_set_bpw(struct stm32_spi *spi)
{
	if (spi->cur_bpw == 16)
		stm32_spi_set_bits(spi, STM32F4_SPI_CR1, STM32F4_SPI_CR1_DFF);
	else
		stm32_spi_clr_bits(spi, STM32F4_SPI_CR1, STM32F4_SPI_CR1_DFF);
}

/**
/**
 * stm32h7_spi_set_bpw - configure bits per word
 * stm32h7_spi_set_bpw - configure bits per word
 * @spi: pointer to the spi controller data structure
 * @spi: pointer to the spi controller data structure
@@ -1053,6 +1457,28 @@ static unsigned int stm32_spi_communication_type(struct spi_device *spi_dev,
	return type;
	return type;
}
}


/**
 * stm32f4_spi_set_mode - configure communication mode
 * @spi: pointer to the spi controller data structure
 * @comm_type: type of communication to configure
 */
static int stm32f4_spi_set_mode(struct stm32_spi *spi, unsigned int comm_type)
{
	if (comm_type == SPI_3WIRE_TX || comm_type == SPI_SIMPLEX_TX) {
		stm32_spi_set_bits(spi, STM32F4_SPI_CR1,
					STM32F4_SPI_CR1_BIDIMODE |
					STM32F4_SPI_CR1_BIDIOE);
	} else if (comm_type == SPI_FULL_DUPLEX) {
		stm32_spi_clr_bits(spi, STM32F4_SPI_CR1,
					STM32F4_SPI_CR1_BIDIMODE |
					STM32F4_SPI_CR1_BIDIOE);
	} else {
		return -EINVAL;
	}

	return 0;
}

/**
/**
 * stm32h7_spi_set_mode - configure communication mode
 * stm32h7_spi_set_mode - configure communication mode
 * @spi: pointer to the spi controller data structure
 * @spi: pointer to the spi controller data structure
@@ -1267,6 +1693,36 @@ static int stm32_spi_unprepare_msg(struct spi_master *master,
	return 0;
	return 0;
}
}


/**
 * stm32f4_spi_config - Configure SPI controller as SPI master
 */
static int stm32f4_spi_config(struct stm32_spi *spi)
{
	unsigned long flags;

	spin_lock_irqsave(&spi->lock, flags);

	/* Ensure I2SMOD bit is kept cleared */
	stm32_spi_clr_bits(spi, STM32F4_SPI_I2SCFGR,
			   STM32F4_SPI_I2SCFGR_I2SMOD);

	/*
	 * - SS input value high
	 * - transmitter half duplex direction
	 * - Set the master mode (default Motorola mode)
	 * - Consider 1 master/n slaves configuration and
	 *   SS input value is determined by the SSI bit
	 */
	stm32_spi_set_bits(spi, STM32F4_SPI_CR1, STM32F4_SPI_CR1_SSI |
						 STM32F4_SPI_CR1_BIDIOE |
						 STM32F4_SPI_CR1_MSTR |
						 STM32F4_SPI_CR1_SSM);

	spin_unlock_irqrestore(&spi->lock, flags);

	return 0;
}

/**
/**
 * stm32h7_spi_config - Configure SPI controller as SPI master
 * stm32h7_spi_config - Configure SPI controller as SPI master
 */
 */
@@ -1304,6 +1760,24 @@ static int stm32h7_spi_config(struct stm32_spi *spi)
	return 0;
	return 0;
}
}


static const struct stm32_spi_cfg stm32f4_spi_cfg = {
	.regs = &stm32f4_spi_regspec,
	.get_bpw_mask = stm32f4_spi_get_bpw_mask,
	.disable = stm32f4_spi_disable,
	.config = stm32f4_spi_config,
	.set_bpw = stm32f4_spi_set_bpw,
	.set_mode = stm32f4_spi_set_mode,
	.transfer_one_dma_start = stm32f4_spi_transfer_one_dma_start,
	.dma_tx_cb = stm32f4_spi_dma_tx_cb,
	.dma_rx_cb = stm32f4_spi_dma_rx_cb,
	.transfer_one_irq = stm32f4_spi_transfer_one_irq,
	.irq_handler_event = stm32f4_spi_irq_event,
	.irq_handler_thread = stm32f4_spi_irq_thread,
	.baud_rate_div_min = STM32F4_SPI_BR_DIV_MIN,
	.baud_rate_div_max = STM32F4_SPI_BR_DIV_MAX,
	.has_fifo = false,
};

static const struct stm32_spi_cfg stm32h7_spi_cfg = {
static const struct stm32_spi_cfg stm32h7_spi_cfg = {
	.regs = &stm32h7_spi_regspec,
	.regs = &stm32h7_spi_regspec,
	.get_fifo_size = stm32h7_spi_get_fifo_size,
	.get_fifo_size = stm32h7_spi_get_fifo_size,
@@ -1326,6 +1800,7 @@ static const struct stm32_spi_cfg stm32h7_spi_cfg = {


static const struct of_device_id stm32_spi_of_match[] = {
static const struct of_device_id stm32_spi_of_match[] = {
	{ .compatible = "st,stm32h7-spi", .data = (void *)&stm32h7_spi_cfg },
	{ .compatible = "st,stm32h7-spi", .data = (void *)&stm32h7_spi_cfg },
	{ .compatible = "st,stm32f4-spi", .data = (void *)&stm32f4_spi_cfg },
	{},
	{},
};
};
MODULE_DEVICE_TABLE(of, stm32_spi_of_match);
MODULE_DEVICE_TABLE(of, stm32_spi_of_match);