mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
spi: axi-spi-engine: Add SPI_CS_HIGH support
The AXI SPI Engine IP core v1.2 added support for SPI_CS_HIGH. This provides the driver implementation to make use of this feature when supported hardware is detected. Signed-off-by: David Lechner <dlechner@baylibre.com> Link: https://msgid.link/r/20240508-spi-axi-spi-engine-add-spi_cs_high-support-v1-1-695dd8e45f00@baylibre.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
f44b3730b0
commit
6ecdb0aa4d
@ -46,6 +46,7 @@
|
||||
#define SPI_ENGINE_INST_ASSERT 0x1
|
||||
#define SPI_ENGINE_INST_WRITE 0x2
|
||||
#define SPI_ENGINE_INST_MISC 0x3
|
||||
#define SPI_ENGINE_INST_CS_INV 0x4
|
||||
|
||||
#define SPI_ENGINE_CMD_REG_CLK_DIV 0x0
|
||||
#define SPI_ENGINE_CMD_REG_CONFIG 0x1
|
||||
@ -73,6 +74,8 @@
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, SPI_ENGINE_MISC_SLEEP, (delay))
|
||||
#define SPI_ENGINE_CMD_SYNC(id) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_MISC, SPI_ENGINE_MISC_SYNC, (id))
|
||||
#define SPI_ENGINE_CMD_CS_INV(flags) \
|
||||
SPI_ENGINE_CMD(SPI_ENGINE_INST_CS_INV, 0, (flags))
|
||||
|
||||
struct spi_engine_program {
|
||||
unsigned int length;
|
||||
@ -111,6 +114,8 @@ struct spi_engine {
|
||||
struct spi_engine_message_state msg_state;
|
||||
struct completion msg_complete;
|
||||
unsigned int int_enable;
|
||||
/* shadows hardware CS inversion flag state */
|
||||
u8 cs_inv;
|
||||
};
|
||||
|
||||
static void spi_engine_program_add_cmd(struct spi_engine_program *p,
|
||||
@ -530,6 +535,29 @@ static int spi_engine_unoptimize_message(struct spi_message *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_engine_setup(struct spi_device *device)
|
||||
{
|
||||
struct spi_controller *host = device->controller;
|
||||
struct spi_engine *spi_engine = spi_controller_get_devdata(host);
|
||||
|
||||
if (device->mode & SPI_CS_HIGH)
|
||||
spi_engine->cs_inv |= BIT(spi_get_chipselect(device, 0));
|
||||
else
|
||||
spi_engine->cs_inv &= ~BIT(spi_get_chipselect(device, 0));
|
||||
|
||||
writel_relaxed(SPI_ENGINE_CMD_CS_INV(spi_engine->cs_inv),
|
||||
spi_engine->base + SPI_ENGINE_REG_CMD_FIFO);
|
||||
|
||||
/*
|
||||
* In addition to setting the flags, we have to do a CS assert command
|
||||
* to make the new setting actually take effect.
|
||||
*/
|
||||
writel_relaxed(SPI_ENGINE_CMD_ASSERT(0, 0xff),
|
||||
spi_engine->base + SPI_ENGINE_REG_CMD_FIFO);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_engine_transfer_one_message(struct spi_controller *host,
|
||||
struct spi_message *msg)
|
||||
{
|
||||
@ -653,6 +681,12 @@ static int spi_engine_probe(struct platform_device *pdev)
|
||||
host->unoptimize_message = spi_engine_unoptimize_message;
|
||||
host->num_chipselect = 8;
|
||||
|
||||
/* Some features depend of the IP core version. */
|
||||
if (ADI_AXI_PCORE_VER_MINOR(version) >= 2) {
|
||||
host->mode_bits |= SPI_CS_HIGH;
|
||||
host->setup = spi_engine_setup;
|
||||
}
|
||||
|
||||
if (host->max_speed_hz == 0)
|
||||
return dev_err_probe(&pdev->dev, -EINVAL, "spi_clk rate is 0");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user