^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Copyright (c) 2009 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // Jaswinder Singh <jassi.brar@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/dmaengine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/platform_data/spi-s3c64xx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define MAX_SPI_PORTS 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define S3C64XX_SPI_QUIRK_POLL (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define S3C64XX_SPI_QUIRK_CS_AUTO (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define AUTOSUSPEND_TIMEOUT 2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* Registers and bit-fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define S3C64XX_SPI_CH_CFG 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define S3C64XX_SPI_CLK_CFG 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define S3C64XX_SPI_MODE_CFG 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define S3C64XX_SPI_CS_REG 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define S3C64XX_SPI_INT_EN 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define S3C64XX_SPI_STATUS 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define S3C64XX_SPI_TX_DATA 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define S3C64XX_SPI_RX_DATA 0x1C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define S3C64XX_SPI_PACKET_CNT 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define S3C64XX_SPI_PENDING_CLR 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define S3C64XX_SPI_SWAP_CFG 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define S3C64XX_SPI_FB_CLK 0x2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define S3C64XX_SPI_CH_HS_EN (1<<6) /* High Speed Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define S3C64XX_SPI_CH_SW_RST (1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define S3C64XX_SPI_CH_SLAVE (1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define S3C64XX_SPI_CPOL_L (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define S3C64XX_SPI_CPHA_B (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define S3C64XX_SPI_CH_RXCH_ON (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define S3C64XX_SPI_CH_TXCH_ON (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define S3C64XX_SPI_CLKSEL_SRCMSK (3<<9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define S3C64XX_SPI_CLKSEL_SRCSHFT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define S3C64XX_SPI_ENCLK_ENABLE (1<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define S3C64XX_SPI_PSR_MASK 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define S3C64XX_SPI_MODE_CH_TSZ_BYTE (0<<29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define S3C64XX_SPI_MODE_CH_TSZ_HALFWORD (1<<29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define S3C64XX_SPI_MODE_CH_TSZ_WORD (2<<29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define S3C64XX_SPI_MODE_CH_TSZ_MASK (3<<29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define S3C64XX_SPI_MODE_BUS_TSZ_BYTE (0<<17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define S3C64XX_SPI_MODE_RXDMA_ON (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define S3C64XX_SPI_MODE_TXDMA_ON (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define S3C64XX_SPI_MODE_4BURST (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define S3C64XX_SPI_CS_NSC_CNT_2 (2<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define S3C64XX_SPI_CS_AUTO (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define S3C64XX_SPI_CS_SIG_INACT (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define S3C64XX_SPI_INT_TRAILING_EN (1<<6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define S3C64XX_SPI_INT_RX_UNDERRUN_EN (1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define S3C64XX_SPI_INT_TX_OVERRUN_EN (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define S3C64XX_SPI_INT_TX_UNDERRUN_EN (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define S3C64XX_SPI_INT_RX_FIFORDY_EN (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define S3C64XX_SPI_INT_TX_FIFORDY_EN (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define S3C64XX_SPI_ST_RX_OVERRUN_ERR (1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define S3C64XX_SPI_ST_RX_UNDERRUN_ERR (1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define S3C64XX_SPI_ST_TX_OVERRUN_ERR (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define S3C64XX_SPI_ST_TX_UNDERRUN_ERR (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define S3C64XX_SPI_ST_RX_FIFORDY (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define S3C64XX_SPI_ST_TX_FIFORDY (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define S3C64XX_SPI_PACKET_CNT_EN (1<<16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define S3C64XX_SPI_PND_RX_UNDERRUN_CLR (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define S3C64XX_SPI_PND_RX_OVERRUN_CLR (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define S3C64XX_SPI_PND_TRAILING_CLR (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define S3C64XX_SPI_SWAP_RX_HALF_WORD (1<<7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define S3C64XX_SPI_SWAP_RX_BYTE (1<<6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define S3C64XX_SPI_SWAP_RX_BIT (1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define S3C64XX_SPI_SWAP_RX_EN (1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define S3C64XX_SPI_SWAP_TX_HALF_WORD (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define S3C64XX_SPI_SWAP_TX_BYTE (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define S3C64XX_SPI_SWAP_TX_BIT (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define S3C64XX_SPI_SWAP_TX_EN (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define S3C64XX_SPI_FBCLK_MSK (3<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) (1 << (i)->port_conf->tx_st_done)) ? 1 : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define TX_FIFO_LVL(v, i) (((v) >> 6) & FIFO_LVL_MASK(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) FIFO_LVL_MASK(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define S3C64XX_SPI_MAX_TRAILCNT 0x3ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define S3C64XX_SPI_TRAILCNT_OFF 19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define is_polling(x) (x->port_conf->quirks & S3C64XX_SPI_QUIRK_POLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define RXBUSY (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define TXBUSY (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct s3c64xx_spi_dma_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct dma_chan *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) dma_cookie_t cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) enum dma_transfer_direction direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * struct s3c64xx_spi_info - SPI Controller hardware info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @tx_st_done: Bit offset of TX_DONE bit in SPI_STATUS regiter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @quirks: Bitmask of known quirks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @high_speed: True, if the controller supports HIGH_SPEED_EN bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @clk_from_cmu: True, if the controller does not include a clock mux and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * prescaler unit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @clk_ioclk: True if clock is present on this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * differ in some aspects such as the size of the fifo and spi bus clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * setup. Such differences are specified to the driver using this structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * which is provided as driver data to the driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct s3c64xx_spi_port_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int fifo_lvl_mask[MAX_SPI_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int rx_lvl_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int tx_st_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) bool high_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) bool clk_from_cmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) bool clk_ioclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * @clk: Pointer to the spi clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * @src_clk: Pointer to the clock used to generate SPI signals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * @ioclk: Pointer to the i/o clock between master and slave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * @pdev: Pointer to device's platform device data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * @master: Pointer to the SPI Protocol master.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * @cntrlr_info: Platform specific data for the controller this driver manages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * @lock: Controller specific lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * @state: Set of FLAGS to indicate status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * @sfr_start: BUS address of SPI controller regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * @regs: Pointer to ioremap'ed controller registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * @xfer_completion: To indicate completion of xfer task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * @cur_mode: Stores the active configuration of the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * @cur_bpw: Stores the active bits per word settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * @cur_speed: Current clock speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * @rx_dma: Local receive DMA data (e.g. chan and direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * @tx_dma: Local transmit DMA data (e.g. chan and direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * @port_conf: Local SPI port configuartion data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * @port_id: Port identification number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct s3c64xx_spi_driver_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) void __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct clk *src_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct clk *ioclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct spi_master *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct s3c64xx_spi_info *cntrlr_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned long sfr_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct completion xfer_completion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsigned state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned cur_mode, cur_bpw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) unsigned cur_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct s3c64xx_spi_dma_data rx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct s3c64xx_spi_dma_data tx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct s3c64xx_spi_port_config *port_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) unsigned int port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) void __iomem *regs = sdd->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned long loops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) writel(0, regs + S3C64XX_SPI_PACKET_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) val = readl(regs + S3C64XX_SPI_CH_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) val &= ~(S3C64XX_SPI_CH_RXCH_ON | S3C64XX_SPI_CH_TXCH_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) writel(val, regs + S3C64XX_SPI_CH_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) val = readl(regs + S3C64XX_SPI_CH_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) val |= S3C64XX_SPI_CH_SW_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) val &= ~S3C64XX_SPI_CH_HS_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) writel(val, regs + S3C64XX_SPI_CH_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /* Flush TxFIFO*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) loops = msecs_to_loops(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) val = readl(regs + S3C64XX_SPI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) } while (TX_FIFO_LVL(val, sdd) && loops--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (loops == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* Flush RxFIFO*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) loops = msecs_to_loops(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) val = readl(regs + S3C64XX_SPI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (RX_FIFO_LVL(val, sdd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) readl(regs + S3C64XX_SPI_RX_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) } while (loops--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (loops == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) val = readl(regs + S3C64XX_SPI_CH_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) val &= ~S3C64XX_SPI_CH_SW_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) writel(val, regs + S3C64XX_SPI_CH_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) val = readl(regs + S3C64XX_SPI_MODE_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) val &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) writel(val, regs + S3C64XX_SPI_MODE_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static void s3c64xx_spi_dmacb(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct s3c64xx_spi_driver_data *sdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct s3c64xx_spi_dma_data *dma = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (dma->direction == DMA_DEV_TO_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) sdd = container_of(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct s3c64xx_spi_driver_data, rx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) sdd = container_of(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct s3c64xx_spi_driver_data, tx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) spin_lock_irqsave(&sdd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (dma->direction == DMA_DEV_TO_MEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) sdd->state &= ~RXBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!(sdd->state & TXBUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) complete(&sdd->xfer_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) sdd->state &= ~TXBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!(sdd->state & RXBUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) complete(&sdd->xfer_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) spin_unlock_irqrestore(&sdd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int prepare_dma(struct s3c64xx_spi_dma_data *dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct sg_table *sgt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct s3c64xx_spi_driver_data *sdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct dma_slave_config config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct dma_async_tx_descriptor *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) memset(&config, 0, sizeof(config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (dma->direction == DMA_DEV_TO_MEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) sdd = container_of((void *)dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct s3c64xx_spi_driver_data, rx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) config.direction = dma->direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) config.src_addr_width = sdd->cur_bpw / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) config.src_maxburst = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dmaengine_slave_config(dma->ch, &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) sdd = container_of((void *)dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct s3c64xx_spi_driver_data, tx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) config.direction = dma->direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) config.dst_addr_width = sdd->cur_bpw / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) config.dst_maxburst = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) dmaengine_slave_config(dma->ch, &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) dma->direction, DMA_PREP_INTERRUPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) dev_err(&sdd->pdev->dev, "unable to prepare %s scatterlist",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dma->direction == DMA_DEV_TO_MEM ? "rx" : "tx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) desc->callback = s3c64xx_spi_dmacb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) desc->callback_param = dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) dma->cookie = dmaengine_submit(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ret = dma_submit_error(dma->cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) dev_err(&sdd->pdev->dev, "DMA submission failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) dma_async_issue_pending(dma->ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static void s3c64xx_spi_set_cs(struct spi_device *spi, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct s3c64xx_spi_driver_data *sdd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) spi_master_get_devdata(spi->master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (sdd->cntrlr_info->no_cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) writel(0, sdd->regs + S3C64XX_SPI_CS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) u32 ssel = readl(sdd->regs + S3C64XX_SPI_CS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ssel |= (S3C64XX_SPI_CS_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) S3C64XX_SPI_CS_NSC_CNT_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) writel(ssel, sdd->regs + S3C64XX_SPI_CS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) writel(S3C64XX_SPI_CS_SIG_INACT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) sdd->regs + S3C64XX_SPI_CS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^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 s3c64xx_spi_prepare_transfer(struct spi_master *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (is_polling(sdd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) spi->dma_rx = sdd->rx_dma.ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) spi->dma_tx = sdd->tx_dma.ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static bool s3c64xx_spi_can_dma(struct spi_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct spi_transfer *xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return xfer->len > (FIFO_LVL_MASK(sdd) >> 1) + 1;
^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 s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct spi_transfer *xfer, int dma_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) void __iomem *regs = sdd->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) u32 modecfg, chcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) modecfg = readl(regs + S3C64XX_SPI_MODE_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) chcfg = readl(regs + S3C64XX_SPI_CH_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) chcfg &= ~S3C64XX_SPI_CH_TXCH_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (dma_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) chcfg &= ~S3C64XX_SPI_CH_RXCH_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* Always shift in data in FIFO, even if xfer is Tx only,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * this helps setting PCKT_CNT value for generating clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * as exactly needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) chcfg |= S3C64XX_SPI_CH_RXCH_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) | S3C64XX_SPI_PACKET_CNT_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) regs + S3C64XX_SPI_PACKET_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (xfer->tx_buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) sdd->state |= TXBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) chcfg |= S3C64XX_SPI_CH_TXCH_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (dma_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) switch (sdd->cur_bpw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) xfer->tx_buf, xfer->len / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) xfer->tx_buf, xfer->len / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) xfer->tx_buf, xfer->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (xfer->rx_buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) sdd->state |= RXBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (sdd->port_conf->high_speed && sdd->cur_speed >= 30000000UL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) && !(sdd->cur_mode & SPI_CPHA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) chcfg |= S3C64XX_SPI_CH_HS_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (dma_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) modecfg |= S3C64XX_SPI_MODE_RXDMA_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) chcfg |= S3C64XX_SPI_CH_RXCH_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) | S3C64XX_SPI_PACKET_CNT_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) regs + S3C64XX_SPI_PACKET_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ret = prepare_dma(&sdd->rx_dma, &xfer->rx_sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^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) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) writel(modecfg, regs + S3C64XX_SPI_MODE_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) writel(chcfg, regs + S3C64XX_SPI_CH_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int timeout_ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) void __iomem *regs = sdd->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) unsigned long val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* max fifo depth available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) u32 max_fifo = (FIFO_LVL_MASK(sdd) >> 1) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (timeout_ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) val = msecs_to_loops(timeout_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) status = readl(regs + S3C64XX_SPI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) } while (RX_FIFO_LVL(status, sdd) < max_fifo && --val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* return the actual received data length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return RX_FIFO_LVL(status, sdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct spi_transfer *xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) void __iomem *regs = sdd->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* millisecs to xfer 'len' bytes @ 'cur_speed' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ms = xfer->len * 8 * 1000 / sdd->cur_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ms += 30; /* some tolerance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ms = max(ms, 100); /* minimum timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) val = msecs_to_jiffies(ms) + 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) val = wait_for_completion_timeout(&sdd->xfer_completion, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * If the previous xfer was completed within timeout, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * proceed further else return -EIO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * DmaTx returns after simply writing data in the FIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * w/o waiting for real transmission on the bus to finish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * DmaRx returns only after Dma read data from FIFO which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * needs bus transmission to finish, so we don't worry if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * Xfer involved Rx(with or without Tx).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (val && !xfer->rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) val = msecs_to_loops(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) status = readl(regs + S3C64XX_SPI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) while ((TX_FIFO_LVL(status, sdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) || !S3C64XX_SPI_ST_TX_DONE(status, sdd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) && --val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) status = readl(regs + S3C64XX_SPI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* If timed out while checking rx/tx status return error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct spi_transfer *xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) void __iomem *regs = sdd->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int loops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) u32 cpy_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) int ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* millisecs to xfer 'len' bytes @ 'cur_speed' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ms = xfer->len * 8 * 1000 / sdd->cur_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) ms += 10; /* some tolerance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) val = msecs_to_loops(ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) status = readl(regs + S3C64XX_SPI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) } while (RX_FIFO_LVL(status, sdd) < xfer->len && --val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* If it was only Tx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (!xfer->rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) sdd->state &= ~TXBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * If the receive length is bigger than the controller fifo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * size, calculate the loops and read the fifo as many times.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * loops = length / max fifo size (calculated by using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * fifo mask).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * For any size less than the fifo size the below code is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * executed atleast once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) loops = xfer->len / ((FIFO_LVL_MASK(sdd) >> 1) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) buf = xfer->rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* wait for data to be received in the fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) cpy_len = s3c64xx_spi_wait_for_timeout(sdd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) (loops ? ms : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) switch (sdd->cur_bpw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ioread32_rep(regs + S3C64XX_SPI_RX_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) buf, cpy_len / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ioread16_rep(regs + S3C64XX_SPI_RX_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) buf, cpy_len / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) ioread8_rep(regs + S3C64XX_SPI_RX_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) buf, cpy_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) buf = buf + cpy_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) } while (loops--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) sdd->state &= ~RXBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) void __iomem *regs = sdd->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* Disable Clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (!sdd->port_conf->clk_from_cmu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) val = readl(regs + S3C64XX_SPI_CLK_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) val &= ~S3C64XX_SPI_ENCLK_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) writel(val, regs + S3C64XX_SPI_CLK_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /* Set Polarity and Phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) val = readl(regs + S3C64XX_SPI_CH_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) val &= ~(S3C64XX_SPI_CH_SLAVE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) S3C64XX_SPI_CPOL_L |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) S3C64XX_SPI_CPHA_B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (sdd->cur_mode & SPI_CPOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) val |= S3C64XX_SPI_CPOL_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (sdd->cur_mode & SPI_CPHA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) val |= S3C64XX_SPI_CPHA_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) writel(val, regs + S3C64XX_SPI_CH_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /* Set Channel & DMA Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) val = readl(regs + S3C64XX_SPI_MODE_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) val &= ~(S3C64XX_SPI_MODE_BUS_TSZ_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) | S3C64XX_SPI_MODE_CH_TSZ_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) switch (sdd->cur_bpw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) val |= S3C64XX_SPI_MODE_CH_TSZ_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) val |= S3C64XX_SPI_MODE_CH_TSZ_HALFWORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) writel(val, regs + S3C64XX_SPI_MODE_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (sdd->port_conf->clk_from_cmu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* The src_clk clock is divided internally by 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ret = clk_set_rate(sdd->src_clk, sdd->cur_speed * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) sdd->cur_speed = clk_get_rate(sdd->src_clk) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /* Configure Clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) val = readl(regs + S3C64XX_SPI_CLK_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) val &= ~S3C64XX_SPI_PSR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) val |= ((clk_get_rate(sdd->src_clk) / sdd->cur_speed / 2 - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) & S3C64XX_SPI_PSR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) writel(val, regs + S3C64XX_SPI_CLK_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /* Enable Clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) val = readl(regs + S3C64XX_SPI_CLK_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) val |= S3C64XX_SPI_ENCLK_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) writel(val, regs + S3C64XX_SPI_CLK_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static int s3c64xx_spi_prepare_message(struct spi_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct spi_message *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct spi_device *spi = msg->spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct s3c64xx_spi_csinfo *cs = spi->controller_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* Configure feedback delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int s3c64xx_spi_transfer_one(struct spi_master *master,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct spi_transfer *xfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) const unsigned int fifo_len = (FIFO_LVL_MASK(sdd) >> 1) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) const void *tx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) void *rx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) int target_len = 0, origin_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) int use_dma = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) u32 speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) u8 bpw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) reinit_completion(&sdd->xfer_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /* Only BPW and Speed may change across transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) bpw = xfer->bits_per_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) speed = xfer->speed_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) sdd->cur_bpw = bpw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) sdd->cur_speed = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) sdd->cur_mode = spi->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) status = s3c64xx_spi_config(sdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (!is_polling(sdd) && (xfer->len > fifo_len) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) sdd->rx_dma.ch && sdd->tx_dma.ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) use_dma = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) } else if (is_polling(sdd) && xfer->len > fifo_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) tx_buf = xfer->tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) rx_buf = xfer->rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) origin_len = xfer->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) target_len = xfer->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (xfer->len > fifo_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) xfer->len = fifo_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) spin_lock_irqsave(&sdd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /* Pending only which is to be done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) sdd->state &= ~RXBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) sdd->state &= ~TXBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* Start the signals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) s3c64xx_spi_set_cs(spi, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) status = s3c64xx_enable_datapath(sdd, xfer, use_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) spin_unlock_irqrestore(&sdd->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) dev_err(&spi->dev, "failed to enable data path for transfer: %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (use_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) status = s3c64xx_wait_for_dma(sdd, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) status = s3c64xx_wait_for_pio(sdd, xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) "I/O Error: rx-%d tx-%d rx-%c tx-%c len-%d dma-%d res-(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) (sdd->state & RXBUSY) ? 'f' : 'p',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) (sdd->state & TXBUSY) ? 'f' : 'p',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) xfer->len, use_dma ? 1 : 0, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (use_dma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct dma_tx_state s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (xfer->tx_buf && (sdd->state & TXBUSY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) dmaengine_pause(sdd->tx_dma.ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) dmaengine_tx_status(sdd->tx_dma.ch, sdd->tx_dma.cookie, &s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) dmaengine_terminate_all(sdd->tx_dma.ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) dev_err(&spi->dev, "TX residue: %d\n", s.residue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (xfer->rx_buf && (sdd->state & RXBUSY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) dmaengine_pause(sdd->rx_dma.ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) dmaengine_tx_status(sdd->rx_dma.ch, sdd->rx_dma.cookie, &s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) dmaengine_terminate_all(sdd->rx_dma.ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) dev_err(&spi->dev, "RX residue: %d\n", s.residue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) s3c64xx_flush_fifo(sdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (target_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) target_len -= xfer->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (xfer->tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) xfer->tx_buf += xfer->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (xfer->rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) xfer->rx_buf += xfer->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (target_len > fifo_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) xfer->len = fifo_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) xfer->len = target_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) } while (target_len > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (origin_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /* Restore original xfer buffers and length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) xfer->tx_buf = tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) xfer->rx_buf = rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) xfer->len = origin_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct s3c64xx_spi_csinfo *cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct device_node *slave_np, *data_np = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) u32 fb_delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) slave_np = spi->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (!slave_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) dev_err(&spi->dev, "device node not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) data_np = of_get_child_by_name(slave_np, "controller-data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (!data_np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) dev_err(&spi->dev, "child node 'controller-data' not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) cs = kzalloc(sizeof(*cs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (!cs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) of_node_put(data_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) cs->fb_delay = fb_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) of_node_put(data_np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * Here we only check the validity of requested configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * and save the configuration in a local data-structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * The controller is actually configured only just before we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * get a message to transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static int s3c64xx_spi_setup(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) struct s3c64xx_spi_csinfo *cs = spi->controller_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct s3c64xx_spi_driver_data *sdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) sdd = spi_master_get_devdata(spi->master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (spi->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) cs = s3c64xx_get_slave_ctrldata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) spi->controller_data = cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) } else if (cs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /* On non-DT platforms the SPI core will set spi->cs_gpio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * to -ENOENT. The GPIO pin used to drive the chip select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * is defined by using platform data so spi->cs_gpio value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * has to be override to have the proper GPIO pin number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) spi->cs_gpio = cs->line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (IS_ERR_OR_NULL(cs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (!spi_get_ctldata(spi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (gpio_is_valid(spi->cs_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) err = gpio_request_one(spi->cs_gpio, GPIOF_OUT_INIT_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) dev_name(&spi->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) "Failed to get /CS gpio [%d]: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) spi->cs_gpio, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) goto err_gpio_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) spi_set_ctldata(spi, cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) pm_runtime_get_sync(&sdd->pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /* Check if we can provide the requested rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (!sdd->port_conf->clk_from_cmu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) u32 psr, speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /* Max possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) speed = clk_get_rate(sdd->src_clk) / 2 / (0 + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (spi->max_speed_hz > speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) spi->max_speed_hz = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) psr = clk_get_rate(sdd->src_clk) / 2 / spi->max_speed_hz - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) psr &= S3C64XX_SPI_PSR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (psr == S3C64XX_SPI_PSR_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) psr--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (spi->max_speed_hz < speed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (psr+1 < S3C64XX_SPI_PSR_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) psr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) goto setup_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (spi->max_speed_hz >= speed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) spi->max_speed_hz = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) dev_err(&spi->dev, "Can't set %dHz transfer speed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) spi->max_speed_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) goto setup_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) pm_runtime_mark_last_busy(&sdd->pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) pm_runtime_put_autosuspend(&sdd->pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) s3c64xx_spi_set_cs(spi, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) setup_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) pm_runtime_mark_last_busy(&sdd->pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) pm_runtime_put_autosuspend(&sdd->pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /* setup() returns with device de-selected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) s3c64xx_spi_set_cs(spi, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (gpio_is_valid(spi->cs_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) gpio_free(spi->cs_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) spi_set_ctldata(spi, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) err_gpio_req:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (spi->dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) kfree(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static void s3c64xx_spi_cleanup(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (gpio_is_valid(spi->cs_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) gpio_free(spi->cs_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (spi->dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) kfree(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /* On non-DT platforms, the SPI core sets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * spi->cs_gpio to -ENOENT and .setup()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * overrides it with the GPIO pin value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * passed using platform data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) spi->cs_gpio = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) spi_set_ctldata(spi, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) struct s3c64xx_spi_driver_data *sdd = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct spi_master *spi = sdd->master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) unsigned int val, clr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) val = readl(sdd->regs + S3C64XX_SPI_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) dev_err(&spi->dev, "RX overrun\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) dev_err(&spi->dev, "RX underrun\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) dev_err(&spi->dev, "TX overrun\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) dev_err(&spi->dev, "TX underrun\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /* Clear the pending irq by setting and then clearing it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) void __iomem *regs = sdd->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) sdd->cur_speed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (sci->no_cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) writel(0, sdd->regs + S3C64XX_SPI_CS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) else if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) writel(S3C64XX_SPI_CS_SIG_INACT, sdd->regs + S3C64XX_SPI_CS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /* Disable Interrupts - we use Polling if not DMA mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) writel(0, regs + S3C64XX_SPI_INT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (!sdd->port_conf->clk_from_cmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) regs + S3C64XX_SPI_CLK_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) writel(0, regs + S3C64XX_SPI_MODE_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) writel(0, regs + S3C64XX_SPI_PACKET_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) /* Clear any irq pending bits, should set and clear the bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) val = S3C64XX_SPI_PND_RX_OVERRUN_CLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) S3C64XX_SPI_PND_RX_UNDERRUN_CLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) S3C64XX_SPI_PND_TX_OVERRUN_CLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) writel(val, regs + S3C64XX_SPI_PENDING_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) writel(0, regs + S3C64XX_SPI_PENDING_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) writel(0, regs + S3C64XX_SPI_SWAP_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) val = readl(regs + S3C64XX_SPI_MODE_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) val &= ~S3C64XX_SPI_MODE_4BURST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) val |= (S3C64XX_SPI_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) writel(val, regs + S3C64XX_SPI_MODE_CFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) s3c64xx_flush_fifo(sdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct s3c64xx_spi_info *sci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) u32 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) sci = devm_kzalloc(dev, sizeof(*sci), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (!sci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) dev_warn(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) sci->src_clk_nr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) sci->src_clk_nr = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (of_property_read_u32(dev->of_node, "num-cs", &temp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) dev_warn(dev, "number of chip select lines not specified, assuming 1 chip select line\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) sci->num_cs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) sci->num_cs = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) sci->no_cs = of_property_read_bool(dev->of_node, "no-cs-readback");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return sci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) return dev_get_platdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static const struct of_device_id s3c64xx_spi_dt_match[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static inline struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (pdev->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) match = of_match_node(s3c64xx_spi_dt_match, pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return (struct s3c64xx_spi_port_config *)match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return (struct s3c64xx_spi_port_config *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) platform_get_device_id(pdev)->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static int s3c64xx_spi_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct resource *mem_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) struct s3c64xx_spi_driver_data *sdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) struct s3c64xx_spi_info *sci = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) struct spi_master *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) int ret, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) char clk_name[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (!sci && pdev->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) sci = s3c64xx_spi_parse_dt(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (IS_ERR(sci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return PTR_ERR(sci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (!sci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) dev_err(&pdev->dev, "platform_data missing!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (mem_res == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) dev_err(&pdev->dev, "Unable to get SPI MEM resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) dev_warn(&pdev->dev, "Failed to get IRQ: %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) master = spi_alloc_master(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) sizeof(struct s3c64xx_spi_driver_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (master == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) dev_err(&pdev->dev, "Unable to allocate SPI Master\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) platform_set_drvdata(pdev, master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) sdd = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) sdd->port_conf = s3c64xx_spi_get_port_config(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) sdd->master = master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) sdd->cntrlr_info = sci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) sdd->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) sdd->sfr_start = mem_res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (pdev->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) ret = of_alias_get_id(pdev->dev.of_node, "spi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) dev_err(&pdev->dev, "failed to get alias id, errno %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) goto err_deref_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) sdd->port_id = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) sdd->port_id = pdev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) sdd->cur_bpw = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) sdd->tx_dma.direction = DMA_MEM_TO_DEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) sdd->rx_dma.direction = DMA_DEV_TO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) master->dev.of_node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) master->bus_num = sdd->port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) master->setup = s3c64xx_spi_setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) master->cleanup = s3c64xx_spi_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) master->prepare_message = s3c64xx_spi_prepare_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) master->transfer_one = s3c64xx_spi_transfer_one;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) master->num_chipselect = sci->num_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) master->dma_alignment = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) SPI_BPW_MASK(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /* the spi->mode bits understood by this driver: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) master->auto_runtime_pm = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (!is_polling(sdd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) master->can_dma = s3c64xx_spi_can_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) sdd->regs = devm_ioremap_resource(&pdev->dev, mem_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (IS_ERR(sdd->regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) ret = PTR_ERR(sdd->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) goto err_deref_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (sci->cfg_gpio && sci->cfg_gpio()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) dev_err(&pdev->dev, "Unable to config gpio\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) goto err_deref_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) /* Setup clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) sdd->clk = devm_clk_get(&pdev->dev, "spi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (IS_ERR(sdd->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) dev_err(&pdev->dev, "Unable to acquire clock 'spi'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) ret = PTR_ERR(sdd->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) goto err_deref_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) ret = clk_prepare_enable(sdd->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) dev_err(&pdev->dev, "Couldn't enable clock 'spi'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) goto err_deref_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) sprintf(clk_name, "spi_busclk%d", sci->src_clk_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) sdd->src_clk = devm_clk_get(&pdev->dev, clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (IS_ERR(sdd->src_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) "Unable to acquire clock '%s'\n", clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) ret = PTR_ERR(sdd->src_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) goto err_disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) ret = clk_prepare_enable(sdd->src_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) goto err_disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (sdd->port_conf->clk_ioclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) sdd->ioclk = devm_clk_get(&pdev->dev, "spi_ioclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (IS_ERR(sdd->ioclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) dev_err(&pdev->dev, "Unable to acquire 'ioclk'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) ret = PTR_ERR(sdd->ioclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) goto err_disable_src_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) ret = clk_prepare_enable(sdd->ioclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) dev_err(&pdev->dev, "Couldn't enable clock 'ioclk'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) goto err_disable_src_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (!is_polling(sdd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* Acquire DMA channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) sdd->rx_dma.ch = dma_request_chan(&pdev->dev, "rx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (IS_ERR(sdd->rx_dma.ch)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) dev_err(&pdev->dev, "Failed to get RX DMA channel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) ret = PTR_ERR(sdd->rx_dma.ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) goto err_disable_io_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) sdd->tx_dma.ch = dma_request_chan(&pdev->dev, "tx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (IS_ERR(sdd->tx_dma.ch)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) dev_err(&pdev->dev, "Failed to get TX DMA channel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) ret = PTR_ERR(sdd->tx_dma.ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) goto err_release_rx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) pm_runtime_use_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) pm_runtime_set_active(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) pm_runtime_get_sync(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) /* Setup Deufult Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) s3c64xx_spi_hwinit(sdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) spin_lock_init(&sdd->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) init_completion(&sdd->xfer_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) ret = devm_request_irq(&pdev->dev, irq, s3c64xx_spi_irq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) "spi-s3c64xx", sdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) dev_err(&pdev->dev, "Failed to request IRQ %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) goto err_pm_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) writel(S3C64XX_SPI_INT_RX_OVERRUN_EN | S3C64XX_SPI_INT_RX_UNDERRUN_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) sdd->regs + S3C64XX_SPI_INT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) ret = devm_spi_register_master(&pdev->dev, master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) dev_err(&pdev->dev, "cannot register SPI master: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) goto err_pm_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Slaves attached\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) sdd->port_id, master->num_chipselect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) mem_res, (FIFO_LVL_MASK(sdd) >> 1) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) pm_runtime_mark_last_busy(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) pm_runtime_put_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) err_pm_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) pm_runtime_put_noidle(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) pm_runtime_set_suspended(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (!is_polling(sdd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) dma_release_channel(sdd->tx_dma.ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) err_release_rx_dma:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (!is_polling(sdd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) dma_release_channel(sdd->rx_dma.ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) err_disable_io_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) clk_disable_unprepare(sdd->ioclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) err_disable_src_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) clk_disable_unprepare(sdd->src_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) err_disable_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) clk_disable_unprepare(sdd->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) err_deref_master:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) spi_master_put(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) static int s3c64xx_spi_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) struct spi_master *master = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) pm_runtime_get_sync(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (!is_polling(sdd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) dma_release_channel(sdd->rx_dma.ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) dma_release_channel(sdd->tx_dma.ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) clk_disable_unprepare(sdd->ioclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) clk_disable_unprepare(sdd->src_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) clk_disable_unprepare(sdd->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) pm_runtime_put_noidle(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) pm_runtime_set_suspended(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) static int s3c64xx_spi_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) struct spi_master *master = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) int ret = spi_master_suspend(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) ret = pm_runtime_force_suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) sdd->cur_speed = 0; /* Output Clock is stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static int s3c64xx_spi_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct spi_master *master = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if (sci->cfg_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) sci->cfg_gpio();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) ret = pm_runtime_force_resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return spi_master_resume(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static int s3c64xx_spi_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) struct spi_master *master = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) clk_disable_unprepare(sdd->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) clk_disable_unprepare(sdd->src_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) clk_disable_unprepare(sdd->ioclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) static int s3c64xx_spi_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) struct spi_master *master = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (sdd->port_conf->clk_ioclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) ret = clk_prepare_enable(sdd->ioclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) ret = clk_prepare_enable(sdd->src_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) goto err_disable_ioclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) ret = clk_prepare_enable(sdd->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) goto err_disable_src_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) s3c64xx_spi_hwinit(sdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) writel(S3C64XX_SPI_INT_RX_OVERRUN_EN | S3C64XX_SPI_INT_RX_UNDERRUN_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) sdd->regs + S3C64XX_SPI_INT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) err_disable_src_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) clk_disable_unprepare(sdd->src_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) err_disable_ioclk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) clk_disable_unprepare(sdd->ioclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) static const struct dev_pm_ops s3c64xx_spi_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) SET_SYSTEM_SLEEP_PM_OPS(s3c64xx_spi_suspend, s3c64xx_spi_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) SET_RUNTIME_PM_OPS(s3c64xx_spi_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) s3c64xx_spi_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) static struct s3c64xx_spi_port_config s3c2443_spi_port_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) .fifo_lvl_mask = { 0x7f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) .rx_lvl_offset = 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) .tx_st_done = 21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) .high_speed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) static struct s3c64xx_spi_port_config s3c6410_spi_port_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) .fifo_lvl_mask = { 0x7f, 0x7F },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) .rx_lvl_offset = 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) .tx_st_done = 21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) .fifo_lvl_mask = { 0x1ff, 0x7F },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) .rx_lvl_offset = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) .tx_st_done = 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) .high_speed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) static struct s3c64xx_spi_port_config exynos4_spi_port_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) .fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) .rx_lvl_offset = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) .tx_st_done = 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) .high_speed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) .clk_from_cmu = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) .quirks = S3C64XX_SPI_QUIRK_CS_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) static struct s3c64xx_spi_port_config exynos7_spi_port_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) .fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F, 0x7F, 0x7F, 0x1ff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) .rx_lvl_offset = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) .tx_st_done = 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) .high_speed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) .clk_from_cmu = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) .quirks = S3C64XX_SPI_QUIRK_CS_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) static struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) .fifo_lvl_mask = { 0x1ff, 0x7f, 0x7f, 0x7f, 0x7f, 0x1ff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) .rx_lvl_offset = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) .tx_st_done = 25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) .high_speed = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .clk_from_cmu = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .clk_ioclk = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) .quirks = S3C64XX_SPI_QUIRK_CS_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) .name = "s3c2443-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) .driver_data = (kernel_ulong_t)&s3c2443_spi_port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) .name = "s3c6410-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) .driver_data = (kernel_ulong_t)&s3c6410_spi_port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) static const struct of_device_id s3c64xx_spi_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) { .compatible = "samsung,s3c2443-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) .data = (void *)&s3c2443_spi_port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) { .compatible = "samsung,s3c6410-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) .data = (void *)&s3c6410_spi_port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) { .compatible = "samsung,s5pv210-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) .data = (void *)&s5pv210_spi_port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) { .compatible = "samsung,exynos4210-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) .data = (void *)&exynos4_spi_port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) { .compatible = "samsung,exynos7-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) .data = (void *)&exynos7_spi_port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) { .compatible = "samsung,exynos5433-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) .data = (void *)&exynos5433_spi_port_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) static struct platform_driver s3c64xx_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) .name = "s3c64xx-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) .pm = &s3c64xx_spi_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) .of_match_table = of_match_ptr(s3c64xx_spi_dt_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) .probe = s3c64xx_spi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) .remove = s3c64xx_spi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) .id_table = s3c64xx_spi_driver_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) MODULE_ALIAS("platform:s3c64xx-spi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) module_platform_driver(s3c64xx_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) MODULE_DESCRIPTION("S3C64XX SPI Controller Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) MODULE_LICENSE("GPL");