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