mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 02:19:51 +00:00
spi: sun6i: add quirk for dual and quad SPI modes support
[ Upstream commit 0605d9fb41
]
New Allwinner's SPI controllers can support dual and quad SPI modes.
To enable one of these modes, we should set the corresponding bit in
the SUN6I_BURST_CTL_CNT_REG register. DRM (28 bits) for dual mode and
Quad_EN (29 bits) for quad transmission.
Signed-off-by: Maksim Kiselev <bigunclemax@gmail.com>
Link: https://lore.kernel.org/r/20230624131632.2972546-2-bigunclemax@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
886c7f95e7
commit
eef4be4cb8
1 changed files with 25 additions and 4 deletions
|
@ -83,6 +83,9 @@
|
|||
#define SUN6I_XMIT_CNT_REG 0x34
|
||||
|
||||
#define SUN6I_BURST_CTL_CNT_REG 0x38
|
||||
#define SUN6I_BURST_CTL_CNT_STC_MASK GENMASK(23, 0)
|
||||
#define SUN6I_BURST_CTL_CNT_DRM BIT(28)
|
||||
#define SUN6I_BURST_CTL_CNT_QUAD_EN BIT(29)
|
||||
|
||||
#define SUN6I_TXDATA_REG 0x200
|
||||
#define SUN6I_RXDATA_REG 0x300
|
||||
|
@ -90,6 +93,7 @@
|
|||
struct sun6i_spi_cfg {
|
||||
unsigned long fifo_depth;
|
||||
bool has_clk_ctl;
|
||||
u32 mode_bits;
|
||||
};
|
||||
|
||||
struct sun6i_spi {
|
||||
|
@ -266,7 +270,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
|||
unsigned int div, div_cdr1, div_cdr2, timeout;
|
||||
unsigned int start, end, tx_time;
|
||||
unsigned int trig_level;
|
||||
unsigned int tx_len = 0, rx_len = 0;
|
||||
unsigned int tx_len = 0, rx_len = 0, nbits = 0;
|
||||
bool use_dma;
|
||||
int ret = 0;
|
||||
u32 reg;
|
||||
|
@ -418,13 +422,29 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
|
|||
sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, reg);
|
||||
|
||||
/* Setup the transfer now... */
|
||||
if (sspi->tx_buf)
|
||||
if (sspi->tx_buf) {
|
||||
tx_len = tfr->len;
|
||||
nbits = tfr->tx_nbits;
|
||||
} else if (tfr->rx_buf) {
|
||||
nbits = tfr->rx_nbits;
|
||||
}
|
||||
|
||||
switch (nbits) {
|
||||
case SPI_NBITS_DUAL:
|
||||
reg = SUN6I_BURST_CTL_CNT_DRM;
|
||||
break;
|
||||
case SPI_NBITS_QUAD:
|
||||
reg = SUN6I_BURST_CTL_CNT_QUAD_EN;
|
||||
break;
|
||||
case SPI_NBITS_SINGLE:
|
||||
default:
|
||||
reg = FIELD_PREP(SUN6I_BURST_CTL_CNT_STC_MASK, tx_len);
|
||||
}
|
||||
|
||||
/* Setup the counters */
|
||||
sun6i_spi_write(sspi, SUN6I_BURST_CTL_CNT_REG, reg);
|
||||
sun6i_spi_write(sspi, SUN6I_BURST_CNT_REG, tfr->len);
|
||||
sun6i_spi_write(sspi, SUN6I_XMIT_CNT_REG, tx_len);
|
||||
sun6i_spi_write(sspi, SUN6I_BURST_CTL_CNT_REG, tx_len);
|
||||
|
||||
if (!use_dma) {
|
||||
/* Fill the TX FIFO */
|
||||
|
@ -623,7 +643,8 @@ static int sun6i_spi_probe(struct platform_device *pdev)
|
|||
master->set_cs = sun6i_spi_set_cs;
|
||||
master->transfer_one = sun6i_spi_transfer_one;
|
||||
master->num_chipselect = 4;
|
||||
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
|
||||
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST |
|
||||
sspi->cfg->mode_bits;
|
||||
master->bits_per_word_mask = SPI_BPW_MASK(8);
|
||||
master->dev.of_node = pdev->dev.of_node;
|
||||
master->auto_runtime_pm = true;
|
||||
|
|
Loading…
Reference in a new issue