1*c26430b7SJon Lin /* 2*c26430b7SJon Lin * Copyright (c) 2022 Rockchip Electronics Co., Ltd 3*c26430b7SJon Lin * 4*c26430b7SJon Lin * SPDX-License-Identifier: GPL-2.0+ 5*c26430b7SJon Lin */ 6*c26430b7SJon Lin 7*c26430b7SJon Lin #ifndef _DRIVER_SPI_H_ 8*c26430b7SJon Lin #define _DRIVER_SPI_H_ 9*c26430b7SJon Lin 10*c26430b7SJon Lin struct rockchip_spi { 11*c26430b7SJon Lin u32 ctrlr0; 12*c26430b7SJon Lin u32 ctrlr1; 13*c26430b7SJon Lin u32 enr; 14*c26430b7SJon Lin u32 ser; 15*c26430b7SJon Lin u32 baudr; 16*c26430b7SJon Lin u32 txftlr; 17*c26430b7SJon Lin u32 rxftlr; 18*c26430b7SJon Lin u32 txflr; 19*c26430b7SJon Lin u32 rxflr; 20*c26430b7SJon Lin u32 sr; 21*c26430b7SJon Lin u32 ipr; 22*c26430b7SJon Lin u32 imr; 23*c26430b7SJon Lin u32 isr; 24*c26430b7SJon Lin u32 risr; 25*c26430b7SJon Lin u32 icr; 26*c26430b7SJon Lin u32 dmacr; 27*c26430b7SJon Lin u32 dmatdlr; 28*c26430b7SJon Lin u32 dmardlr; /* 0x44 */ 29*c26430b7SJon Lin u32 reserved[0xef]; 30*c26430b7SJon Lin u32 txdr[0x100]; /* 0x400 */ 31*c26430b7SJon Lin u32 rxdr[0x100]; /* 0x800 */ 32*c26430b7SJon Lin }; 33*c26430b7SJon Lin 34*c26430b7SJon Lin /* CTRLR0 */ 35*c26430b7SJon Lin enum { 36*c26430b7SJon Lin DFS_SHIFT = 0, /* Data Frame Size */ 37*c26430b7SJon Lin DFS_MASK = 3, 38*c26430b7SJon Lin DFS_4BIT = 0, 39*c26430b7SJon Lin DFS_8BIT, 40*c26430b7SJon Lin DFS_16BIT, 41*c26430b7SJon Lin DFS_RESV, 42*c26430b7SJon Lin 43*c26430b7SJon Lin CFS_SHIFT = 2, /* Control Frame Size */ 44*c26430b7SJon Lin CFS_MASK = 0xf, 45*c26430b7SJon Lin 46*c26430b7SJon Lin SCPH_SHIFT = 6, /* Serial Clock Phase */ 47*c26430b7SJon Lin SCPH_MASK = 1, 48*c26430b7SJon Lin SCPH_TOGMID = 0, /* SCLK toggles in middle of first data bit */ 49*c26430b7SJon Lin SCPH_TOGSTA, /* SCLK toggles at start of first data bit */ 50*c26430b7SJon Lin 51*c26430b7SJon Lin SCOL_SHIFT = 7, /* Serial Clock Polarity */ 52*c26430b7SJon Lin SCOL_MASK = 1, 53*c26430b7SJon Lin SCOL_LOW = 0, /* Inactive state of serial clock is low */ 54*c26430b7SJon Lin SCOL_HIGH, /* Inactive state of serial clock is high */ 55*c26430b7SJon Lin 56*c26430b7SJon Lin CSM_SHIFT = 8, /* Chip Select Mode */ 57*c26430b7SJon Lin CSM_MASK = 0x3, 58*c26430b7SJon Lin CSM_KEEP = 0, /* ss_n stays low after each frame */ 59*c26430b7SJon Lin CSM_HALF, /* ss_n high for half sclk_out cycles */ 60*c26430b7SJon Lin CSM_ONE, /* ss_n high for one sclk_out cycle */ 61*c26430b7SJon Lin CSM_RESV, 62*c26430b7SJon Lin 63*c26430b7SJon Lin SSN_DELAY_SHIFT = 10, /* SSN to Sclk_out delay */ 64*c26430b7SJon Lin SSN_DELAY_MASK = 1, 65*c26430b7SJon Lin SSN_DELAY_HALF = 0, /* 1/2 sclk_out cycle */ 66*c26430b7SJon Lin SSN_DELAY_ONE = 1, /* 1 sclk_out cycle */ 67*c26430b7SJon Lin 68*c26430b7SJon Lin SEM_SHIFT = 11, /* Serial Endian Mode */ 69*c26430b7SJon Lin SEM_MASK = 1, 70*c26430b7SJon Lin SEM_LITTLE = 0, /* little endian */ 71*c26430b7SJon Lin SEM_BIG, /* big endian */ 72*c26430b7SJon Lin 73*c26430b7SJon Lin FBM_SHIFT = 12, /* First Bit Mode */ 74*c26430b7SJon Lin FBM_MASK = 1, 75*c26430b7SJon Lin FBM_MSB = 0, /* first bit is MSB */ 76*c26430b7SJon Lin FBM_LSB, /* first bit in LSB */ 77*c26430b7SJon Lin 78*c26430b7SJon Lin HALF_WORD_TX_SHIFT = 13, /* Byte and Halfword Transform */ 79*c26430b7SJon Lin HALF_WORD_MASK = 1, 80*c26430b7SJon Lin HALF_WORD_ON = 0, /* apb 16bit write/read, spi 8bit write/read */ 81*c26430b7SJon Lin HALF_WORD_OFF, /* apb 8bit write/read, spi 8bit write/read */ 82*c26430b7SJon Lin 83*c26430b7SJon Lin RXDSD_SHIFT = 14, /* Rxd Sample Delay, in cycles */ 84*c26430b7SJon Lin RXDSD_MASK = 3, 85*c26430b7SJon Lin 86*c26430b7SJon Lin FRF_SHIFT = 16, /* Frame Format */ 87*c26430b7SJon Lin FRF_MASK = 3, 88*c26430b7SJon Lin FRF_SPI = 0, /* Motorola SPI */ 89*c26430b7SJon Lin FRF_SSP, /* Texas Instruments SSP*/ 90*c26430b7SJon Lin FRF_MICROWIRE, /* National Semiconductors Microwire */ 91*c26430b7SJon Lin FRF_RESV, 92*c26430b7SJon Lin 93*c26430b7SJon Lin TMOD_SHIFT = 18, /* Transfer Mode */ 94*c26430b7SJon Lin TMOD_MASK = 3, 95*c26430b7SJon Lin TMOD_TR = 0, /* xmit & recv */ 96*c26430b7SJon Lin TMOD_TO, /* xmit only */ 97*c26430b7SJon Lin TMOD_RO, /* recv only */ 98*c26430b7SJon Lin TMOD_RESV, 99*c26430b7SJon Lin 100*c26430b7SJon Lin OMOD_SHIFT = 20, /* Operation Mode */ 101*c26430b7SJon Lin OMOD_MASK = 1, 102*c26430b7SJon Lin OMOD_MASTER = 0, /* Master Mode */ 103*c26430b7SJon Lin OMOD_SLAVE, /* Slave Mode */ 104*c26430b7SJon Lin }; 105*c26430b7SJon Lin 106*c26430b7SJon Lin /* SR */ 107*c26430b7SJon Lin enum { 108*c26430b7SJon Lin SR_MASK = 0x7f, 109*c26430b7SJon Lin SR_BUSY = 1 << 0, 110*c26430b7SJon Lin SR_TF_FULL = 1 << 1, 111*c26430b7SJon Lin SR_TF_EMPT = 1 << 2, 112*c26430b7SJon Lin SR_RF_EMPT = 1 << 3, 113*c26430b7SJon Lin SR_RF_FULL = 1 << 4, 114*c26430b7SJon Lin }; 115*c26430b7SJon Lin 116*c26430b7SJon Lin #define ROCKCHIP_SPI_TIMEOUT_MS 1000 117*c26430b7SJon Lin 118*c26430b7SJon Lin #define SPI_XFER_BEGIN BIT(0) /* Assert CS before transfer */ 119*c26430b7SJon Lin #define SPI_XFER_END BIT(1) /* Deassert CS after transfer */ 120*c26430b7SJon Lin #define SPI_XFER_ONCE (SPI_XFER_BEGIN | SPI_XFER_END) 121*c26430b7SJon Lin 122*c26430b7SJon Lin /* SPI mode flags */ 123*c26430b7SJon Lin #define SPI_CPHA BIT(0) /* clock phase */ 124*c26430b7SJon Lin #define SPI_CPOL BIT(1) /* clock polarity */ 125*c26430b7SJon Lin #define SPI_MODE_0 (0 | 0) /* (original MicroWire) */ 126*c26430b7SJon Lin #define SPI_MODE_1 (0 | SPI_CPHA) 127*c26430b7SJon Lin #define SPI_MODE_2 (SPI_CPOL | 0) 128*c26430b7SJon Lin #define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) 129*c26430b7SJon Lin 130*c26430b7SJon Lin int rockchip_spi_probe(u8 bus, uintptr_t base_addr, u32 rsd, u32 clock_div, u32 mode); 131*c26430b7SJon Lin int rockchip_spi_claim_bus(u8 bus); 132*c26430b7SJon Lin void rockchip_spi_release_bus(u8 bus); 133*c26430b7SJon Lin int rockchip_spi_xfer(u8 bus, u8 cs, unsigned int bitlen, const void *dout, void *din, unsigned long flags); 134*c26430b7SJon Lin int rockchip_spi_write_then_read(u8 bus, u8 cs, 135*c26430b7SJon Lin const u8 *opcode, size_t n_opcode, 136*c26430b7SJon Lin const u8 *txbuf, u8 *rxbuf, size_t n_buf); 137*c26430b7SJon Lin 138*c26430b7SJon Lin #endif 139