^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2003-2015 Broadcom Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /* SPI Configuration Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define XLP_SPI_CONFIG 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define XLP_SPI_CPHA BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define XLP_SPI_CPOL BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define XLP_SPI_CS_POL BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define XLP_SPI_TXMISO_EN BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define XLP_SPI_TXMOSI_EN BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define XLP_SPI_RXMISO_EN BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define XLP_SPI_CS_LSBFE BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define XLP_SPI_RXCAP_EN BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* SPI Frequency Divider Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define XLP_SPI_FDIV 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* SPI Command Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define XLP_SPI_CMD 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define XLP_SPI_CMD_IDLE_MASK 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define XLP_SPI_CMD_TX_MASK 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define XLP_SPI_CMD_RX_MASK 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define XLP_SPI_CMD_TXRX_MASK 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define XLP_SPI_CMD_CONT BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define XLP_SPI_XFR_BITCNT_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* SPI Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define XLP_SPI_STATUS 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define XLP_SPI_XFR_PENDING BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define XLP_SPI_XFR_DONE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define XLP_SPI_TX_INT BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define XLP_SPI_RX_INT BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define XLP_SPI_TX_UF BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define XLP_SPI_RX_OF BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define XLP_SPI_STAT_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* SPI Interrupt Enable Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define XLP_SPI_INTR_EN 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define XLP_SPI_INTR_DONE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define XLP_SPI_INTR_TXTH BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define XLP_SPI_INTR_RXTH BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define XLP_SPI_INTR_TXUF BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define XLP_SPI_INTR_RXOF BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* SPI FIFO Threshold Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define XLP_SPI_FIFO_THRESH 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* SPI FIFO Word Count Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define XLP_SPI_FIFO_WCNT 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define XLP_SPI_RXFIFO_WCNT_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define XLP_SPI_TXFIFO_WCNT_MASK 0xf0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define XLP_SPI_TXFIFO_WCNT_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* SPI Transmit Data FIFO Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define XLP_SPI_TXDATA_FIFO 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* SPI Receive Data FIFO Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define XLP_SPI_RXDATA_FIFO 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* SPI System Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define XLP_SPI_SYSCTRL 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define XLP_SPI_SYS_RESET BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define XLP_SPI_SYS_CLKDIS BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define XLP_SPI_SYS_PMEN BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SPI_CS_OFFSET 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define XLP_SPI_TXRXTH 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define XLP_SPI_FIFO_SIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define XLP_SPI_MAX_CS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define XLP_SPI_DEFAULT_FREQ 133333333
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define XLP_SPI_FDIV_MIN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define XLP_SPI_FDIV_MAX 65535
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * SPI can transfer only 28 bytes properly at a time. So split the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * transfer into 28 bytes size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define XLP_SPI_XFER_SIZE 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct xlp_spi_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct device dev; /* device structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) void __iomem *base; /* spi registers base address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) const u8 *tx_buf; /* tx data buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) u8 *rx_buf; /* rx data buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int tx_len; /* tx xfer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int rx_len; /* rx xfer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int txerrors; /* TXFIFO underflow count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int rxerrors; /* RXFIFO overflow count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int cs; /* slave device chip select */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u32 spi_clk; /* spi clock frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) bool cmd_cont; /* cs active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct completion done; /* completion notification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static inline u32 xlp_spi_reg_read(struct xlp_spi_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int cs, int regoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return readl(priv->base + regoff + cs * SPI_CS_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static inline void xlp_spi_reg_write(struct xlp_spi_priv *priv, int cs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int regoff, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) writel(val, priv->base + regoff + cs * SPI_CS_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static inline void xlp_spi_sysctl_write(struct xlp_spi_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int regoff, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) writel(val, priv->base + regoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * Setup global SPI_SYSCTRL register for all SPI channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static void xlp_spi_sysctl_setup(struct xlp_spi_priv *xspi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) for (cs = 0; cs < XLP_SPI_MAX_CS; cs++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) xlp_spi_sysctl_write(xspi, XLP_SPI_SYSCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) XLP_SPI_SYS_RESET << cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) xlp_spi_sysctl_write(xspi, XLP_SPI_SYSCTRL, XLP_SPI_SYS_PMEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static int xlp_spi_setup(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct xlp_spi_priv *xspi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u32 fdiv, cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) xspi = spi_master_get_devdata(spi->master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) cs = spi->chip_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * The value of fdiv must be between 4 and 65535.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) fdiv = DIV_ROUND_UP(xspi->spi_clk, spi->max_speed_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (fdiv > XLP_SPI_FDIV_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) fdiv = XLP_SPI_FDIV_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) else if (fdiv < XLP_SPI_FDIV_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) fdiv = XLP_SPI_FDIV_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) xlp_spi_reg_write(xspi, cs, XLP_SPI_FDIV, fdiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) xlp_spi_reg_write(xspi, cs, XLP_SPI_FIFO_THRESH, XLP_SPI_TXRXTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) cfg = xlp_spi_reg_read(xspi, cs, XLP_SPI_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (spi->mode & SPI_CPHA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) cfg |= XLP_SPI_CPHA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) cfg &= ~XLP_SPI_CPHA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (spi->mode & SPI_CPOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) cfg |= XLP_SPI_CPOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) cfg &= ~XLP_SPI_CPOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (!(spi->mode & SPI_CS_HIGH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) cfg |= XLP_SPI_CS_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) cfg &= ~XLP_SPI_CS_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (spi->mode & SPI_LSB_FIRST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) cfg |= XLP_SPI_CS_LSBFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) cfg &= ~XLP_SPI_CS_LSBFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) cfg |= XLP_SPI_TXMOSI_EN | XLP_SPI_RXMISO_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (fdiv == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) cfg |= XLP_SPI_RXCAP_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) xlp_spi_reg_write(xspi, cs, XLP_SPI_CONFIG, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static void xlp_spi_read_rxfifo(struct xlp_spi_priv *xspi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u32 rx_data, rxfifo_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int i, j, nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) rxfifo_cnt = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_FIFO_WCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) rxfifo_cnt &= XLP_SPI_RXFIFO_WCNT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) while (rxfifo_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) rx_data = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_RXDATA_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) nbytes = min(xspi->rx_len, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) for (i = nbytes - 1; i >= 0; i--, j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) xspi->rx_buf[i] = (rx_data >> (j * 8)) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) xspi->rx_len -= nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) xspi->rx_buf += nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) rxfifo_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static void xlp_spi_fill_txfifo(struct xlp_spi_priv *xspi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u32 tx_data, txfifo_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int i, j, nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) txfifo_cnt = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_FIFO_WCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) txfifo_cnt &= XLP_SPI_TXFIFO_WCNT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) txfifo_cnt >>= XLP_SPI_TXFIFO_WCNT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) while (xspi->tx_len && (txfifo_cnt < XLP_SPI_FIFO_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) tx_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) nbytes = min(xspi->tx_len, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) for (i = nbytes - 1; i >= 0; i--, j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) tx_data |= xspi->tx_buf[i] << (j * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_TXDATA_FIFO, tx_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) xspi->tx_len -= nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) xspi->tx_buf += nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) txfifo_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static irqreturn_t xlp_spi_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct xlp_spi_priv *xspi = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) u32 stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) stat = xlp_spi_reg_read(xspi, xspi->cs, XLP_SPI_STATUS) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) XLP_SPI_STAT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (stat & XLP_SPI_TX_INT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (xspi->tx_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) xlp_spi_fill_txfifo(xspi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (stat & XLP_SPI_TX_UF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) xspi->txerrors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (stat & XLP_SPI_RX_INT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (xspi->rx_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) xlp_spi_read_rxfifo(xspi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (stat & XLP_SPI_RX_OF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) xspi->rxerrors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* write status back to clear interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_STATUS, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (stat & XLP_SPI_XFR_DONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) complete(&xspi->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static void xlp_spi_send_cmd(struct xlp_spi_priv *xspi, int xfer_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int cmd_cont)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) u32 cmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (xspi->tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) cmd |= XLP_SPI_CMD_TX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (xspi->rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) cmd |= XLP_SPI_CMD_RX_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (cmd_cont)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) cmd |= XLP_SPI_CMD_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) cmd |= ((xfer_len * 8 - 1) << XLP_SPI_XFR_BITCNT_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) xlp_spi_reg_write(xspi, xspi->cs, XLP_SPI_CMD, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static int xlp_spi_xfer_block(struct xlp_spi_priv *xs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) const unsigned char *tx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) unsigned char *rx_buf, int xfer_len, int cmd_cont)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) u32 intr_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) xs->tx_buf = tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) xs->rx_buf = rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) xs->tx_len = (xs->tx_buf == NULL) ? 0 : xfer_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) xs->rx_len = (xs->rx_buf == NULL) ? 0 : xfer_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) xs->txerrors = xs->rxerrors = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* fill TXDATA_FIFO, then send the CMD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (xs->tx_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) xlp_spi_fill_txfifo(xs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) xlp_spi_send_cmd(xs, xfer_len, cmd_cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * We are getting some spurious tx interrupts, so avoid enabling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * tx interrupts when only rx is in process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * Enable all the interrupts in tx case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (xs->tx_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) intr_mask |= XLP_SPI_INTR_TXTH | XLP_SPI_INTR_TXUF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) XLP_SPI_INTR_RXTH | XLP_SPI_INTR_RXOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) intr_mask |= XLP_SPI_INTR_RXTH | XLP_SPI_INTR_RXOF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) intr_mask |= XLP_SPI_INTR_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) xlp_spi_reg_write(xs, xs->cs, XLP_SPI_INTR_EN, intr_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) timeout = wait_for_completion_timeout(&xs->done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* Disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) xlp_spi_reg_write(xs, xs->cs, XLP_SPI_INTR_EN, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (!timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) dev_err(&xs->dev, "xfer timedout!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (xs->txerrors || xs->rxerrors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) dev_err(&xs->dev, "Over/Underflow rx %d tx %d xfer %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) xs->rxerrors, xs->txerrors, xfer_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return xfer_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int xlp_spi_txrx_bufs(struct xlp_spi_priv *xs, struct spi_transfer *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int bytesleft, sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) unsigned char *rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) const unsigned char *tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) tx_buf = t->tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) rx_buf = t->rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) bytesleft = t->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) while (bytesleft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (bytesleft > XLP_SPI_XFER_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) sz = xlp_spi_xfer_block(xs, tx_buf, rx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) XLP_SPI_XFER_SIZE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) sz = xlp_spi_xfer_block(xs, tx_buf, rx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) bytesleft, xs->cmd_cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (sz < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) bytesleft -= sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) tx_buf += sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) rx_buf += sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return bytesleft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int xlp_spi_transfer_one(struct spi_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct spi_transfer *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct xlp_spi_priv *xspi = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) xspi->cs = spi->chip_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) xspi->dev = spi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (spi_transfer_is_last(master, t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) xspi->cmd_cont = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) xspi->cmd_cont = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (xlp_spi_txrx_bufs(xspi, t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) spi_finalize_current_transfer(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static int xlp_spi_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct spi_master *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct xlp_spi_priv *xspi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) int irq, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) xspi = devm_kzalloc(&pdev->dev, sizeof(*xspi), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (!xspi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) xspi->base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (IS_ERR(xspi->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return PTR_ERR(xspi->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) err = devm_request_irq(&pdev->dev, irq, xlp_spi_interrupt, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) pdev->name, xspi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) dev_err(&pdev->dev, "unable to request irq %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) clk = devm_clk_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) dev_err(&pdev->dev, "could not get spi clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) xspi->spi_clk = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) master = spi_alloc_master(&pdev->dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (!master) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) dev_err(&pdev->dev, "could not alloc master\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) master->bus_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) master->num_chipselect = XLP_SPI_MAX_CS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) master->setup = xlp_spi_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) master->transfer_one = xlp_spi_transfer_one;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) master->dev.of_node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) init_completion(&xspi->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) spi_master_set_devdata(master, xspi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) xlp_spi_sysctl_setup(xspi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* register spi controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) err = devm_spi_register_master(&pdev->dev, master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dev_err(&pdev->dev, "spi register master failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) spi_master_put(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static const struct acpi_device_id xlp_spi_acpi_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) { "BRCM900D", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) { "CAV900D", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) MODULE_DEVICE_TABLE(acpi, xlp_spi_acpi_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static const struct of_device_id xlp_spi_dt_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) { .compatible = "netlogic,xlp832-spi" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) MODULE_DEVICE_TABLE(of, xlp_spi_dt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static struct platform_driver xlp_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .probe = xlp_spi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .name = "xlp-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .of_match_table = xlp_spi_dt_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .acpi_match_table = ACPI_PTR(xlp_spi_acpi_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) module_platform_driver(xlp_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) MODULE_AUTHOR("Kamlakant Patel <kamlakant.patel@broadcom.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) MODULE_DESCRIPTION("Netlogic XLP SPI controller driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) MODULE_LICENSE("GPL v2");