Commit f9c6ef6c authored by Ricardo Ribalda Delgado's avatar Ricardo Ribalda Delgado Committed by Mark Brown

spi/xilinx: Support for spi mode CS_HIGH

The core controls the chip select lines individually.

By default, all the lines are consider active_low. After
spi_setup_transfer, it has its real value.
Signed-off-by: default avatarRicardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent d9f58812
...@@ -89,6 +89,7 @@ struct xilinx_spi { ...@@ -89,6 +89,7 @@ struct xilinx_spi {
int remaining_bytes; /* the number of bytes left to transfer */ int remaining_bytes; /* the number of bytes left to transfer */
u8 bits_per_word; u8 bits_per_word;
int buffer_size; /* buffer size in words */ int buffer_size; /* buffer size in words */
u32 cs_inactive; /* Level of the CS pins when inactive*/
unsigned int (*read_fn)(void __iomem *); unsigned int (*read_fn)(void __iomem *);
void (*write_fn)(u32, void __iomem *); void (*write_fn)(u32, void __iomem *);
void (*tx_fn)(struct xilinx_spi *); void (*tx_fn)(struct xilinx_spi *);
...@@ -194,14 +195,17 @@ static void xspi_init_hw(struct xilinx_spi *xspi) ...@@ -194,14 +195,17 @@ static void xspi_init_hw(struct xilinx_spi *xspi)
static void xilinx_spi_chipselect(struct spi_device *spi, int is_on) static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
{ {
struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); struct xilinx_spi *xspi = spi_master_get_devdata(spi->master);
u16 cr;
u32 cs;
if (is_on == BITBANG_CS_INACTIVE) { if (is_on == BITBANG_CS_INACTIVE) {
/* Deselect the slave on the SPI bus */ /* Deselect the slave on the SPI bus */
xspi->write_fn(0xffff, xspi->regs + XSPI_SSR_OFFSET); xspi->write_fn(xspi->cs_inactive, xspi->regs + XSPI_SSR_OFFSET);
} else if (is_on == BITBANG_CS_ACTIVE) { return;
}
/* Set the SPI clock phase and polarity */ /* Set the SPI clock phase and polarity */
u16 cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) & ~XSPI_CR_MODE_MASK;
& ~XSPI_CR_MODE_MASK;
if (spi->mode & SPI_CPHA) if (spi->mode & SPI_CPHA)
cr |= XSPI_CR_CPHA; cr |= XSPI_CR_CPHA;
if (spi->mode & SPI_CPOL) if (spi->mode & SPI_CPOL)
...@@ -217,10 +221,11 @@ static void xilinx_spi_chipselect(struct spi_device *spi, int is_on) ...@@ -217,10 +221,11 @@ static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
* parameter) * parameter)
*/ */
cs = xspi->cs_inactive;
cs ^= BIT(spi->chip_select);
/* Activate the chip select */ /* Activate the chip select */
xspi->write_fn(~(0x0001 << spi->chip_select), xspi->write_fn(cs, xspi->regs + XSPI_SSR_OFFSET);
xspi->regs + XSPI_SSR_OFFSET);
}
} }
/* spi_bitbang requires custom setup_transfer() to be defined if there is a /* spi_bitbang requires custom setup_transfer() to be defined if there is a
...@@ -229,6 +234,13 @@ static void xilinx_spi_chipselect(struct spi_device *spi, int is_on) ...@@ -229,6 +234,13 @@ static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
static int xilinx_spi_setup_transfer(struct spi_device *spi, static int xilinx_spi_setup_transfer(struct spi_device *spi,
struct spi_transfer *t) struct spi_transfer *t)
{ {
struct xilinx_spi *xspi = spi_master_get_devdata(spi->master);
if (spi->mode & SPI_CS_HIGH)
xspi->cs_inactive &= ~BIT(spi->chip_select);
else
xspi->cs_inactive |= BIT(spi->chip_select);
return 0; return 0;
} }
...@@ -376,9 +388,11 @@ static int xilinx_spi_probe(struct platform_device *pdev) ...@@ -376,9 +388,11 @@ static int xilinx_spi_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
/* the spi->mode bits understood by this driver: */ /* the spi->mode bits understood by this driver: */
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP |
SPI_CS_HIGH;
xspi = spi_master_get_devdata(master); xspi = spi_master_get_devdata(master);
xspi->cs_inactive = 0xffffffff;
xspi->bitbang.master = master; xspi->bitbang.master = master;
xspi->bitbang.chipselect = xilinx_spi_chipselect; xspi->bitbang.chipselect = xilinx_spi_chipselect;
xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer; xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment