1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * LPC32xx SSP interface (SPI mode) 4 * 5 * (C) Copyright 2014 DENX Software Engineering GmbH 6 * Written-by: Albert ARIBAUD <albert.aribaud@3adev.fr> 7 */ 8 9 #include <common.h> 10 #include <linux/compat.h> 11 #include <asm/io.h> 12 #include <malloc.h> 13 #include <spi.h> 14 #include <asm/arch/clk.h> 15 16 /* SSP chip registers */ 17 struct ssp_regs { 18 u32 cr0; 19 u32 cr1; 20 u32 data; 21 u32 sr; 22 u32 cpsr; 23 u32 imsc; 24 u32 ris; 25 u32 mis; 26 u32 icr; 27 u32 dmacr; 28 }; 29 30 /* CR1 register defines */ 31 #define SSP_CR1_SSP_ENABLE 0x0002 32 33 /* SR register defines */ 34 #define SSP_SR_TNF 0x0002 35 /* SSP status RX FIFO not empty bit */ 36 #define SSP_SR_RNE 0x0004 37 38 /* lpc32xx spi slave */ 39 struct lpc32xx_spi_slave { 40 struct spi_slave slave; 41 struct ssp_regs *regs; 42 }; 43 44 static inline struct lpc32xx_spi_slave *to_lpc32xx_spi_slave( 45 struct spi_slave *slave) 46 { 47 return container_of(slave, struct lpc32xx_spi_slave, slave); 48 } 49 50 /* the following is called in sequence by do_spi_xfer() */ 51 52 struct spi_slave *spi_setup_slave(uint bus, uint cs, uint max_hz, uint mode) 53 { 54 struct lpc32xx_spi_slave *lslave; 55 56 /* we only set up SSP0 for now, so ignore bus */ 57 58 if (mode & SPI_3WIRE) { 59 pr_err("3-wire mode not supported"); 60 return NULL; 61 } 62 63 if (mode & SPI_SLAVE) { 64 pr_err("slave mode not supported\n"); 65 return NULL; 66 } 67 68 if (mode & SPI_PREAMBLE) { 69 pr_err("preamble byte skipping not supported\n"); 70 return NULL; 71 } 72 73 lslave = spi_alloc_slave(struct lpc32xx_spi_slave, bus, cs); 74 if (!lslave) { 75 printf("SPI_error: Fail to allocate lpc32xx_spi_slave\n"); 76 return NULL; 77 } 78 79 lslave->regs = (struct ssp_regs *)SSP0_BASE; 80 81 /* 82 * 8 bit frame, SPI fmt, 500kbps -> clock divider is 26. 83 * Set SCR to 0 and CPSDVSR to 26. 84 */ 85 86 writel(0x7, &lslave->regs->cr0); /* 8-bit chunks, SPI, 1 clk/bit */ 87 writel(26, &lslave->regs->cpsr); /* SSP clock = HCLK/26 = 500kbps */ 88 writel(0, &lslave->regs->imsc); /* do not raise any interrupts */ 89 writel(0, &lslave->regs->icr); /* clear any pending interrupt */ 90 writel(0, &lslave->regs->dmacr); /* do not do DMAs */ 91 writel(SSP_CR1_SSP_ENABLE, &lslave->regs->cr1); /* enable SSP0 */ 92 return &lslave->slave; 93 } 94 95 void spi_free_slave(struct spi_slave *slave) 96 { 97 struct lpc32xx_spi_slave *lslave = to_lpc32xx_spi_slave(slave); 98 99 debug("(lpc32xx) spi_free_slave: 0x%08x\n", (u32)lslave); 100 free(lslave); 101 } 102 103 int spi_claim_bus(struct spi_slave *slave) 104 { 105 /* only one bus and slave so far, always available */ 106 return 0; 107 } 108 109 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, 110 const void *dout, void *din, unsigned long flags) 111 { 112 struct lpc32xx_spi_slave *lslave = to_lpc32xx_spi_slave(slave); 113 int bytelen = bitlen >> 3; 114 int idx_out = 0; 115 int idx_in = 0; 116 int start_time; 117 118 start_time = get_timer(0); 119 while ((idx_out < bytelen) || (idx_in < bytelen)) { 120 int status = readl(&lslave->regs->sr); 121 if ((idx_out < bytelen) && (status & SSP_SR_TNF)) 122 writel(((u8 *)dout)[idx_out++], &lslave->regs->data); 123 if ((idx_in < bytelen) && (status & SSP_SR_RNE)) 124 ((u8 *)din)[idx_in++] = readl(&lslave->regs->data); 125 if (get_timer(start_time) >= CONFIG_LPC32XX_SSP_TIMEOUT) 126 return -1; 127 } 128 return 0; 129 } 130 131 void spi_release_bus(struct spi_slave *slave) 132 { 133 /* do nothing */ 134 } 135