1 /* 2 * Copyright (C) 2006 Michael Brown <mbrown (at) fensystems.co.uk>. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 FILE_LICENCE ( GPL2_OR_LATER ); 20 21 #include <stddef.h> 22 #include <stdint.h> 23 #include <string.h> 24 #include <byteswap.h> 25 #include <errno.h> 26 #include <assert.h> 27 #include <unistd.h> 28 #include <gpxe/bitbash.h> 29 #include <gpxe/spi_bit.h> 30 31 /** @file 32 * 33 * SPI bit-bashing interface 34 * 35 */ 36 37 /** Delay between SCLK changes and around SS changes */ 38 static void spi_bit_delay ( void ) { 39 udelay ( SPI_BIT_UDELAY ); 40 } 41 42 /** Chip select line will be asserted */ 43 #define SELECT_SLAVE 0 44 45 /** Chip select line will be deasserted */ 46 #define DESELECT_SLAVE SPI_MODE_SSPOL 47 48 /** 49 * Select/deselect slave 50 * 51 * @v spibit SPI bit-bashing interface 52 * @v slave Slave number 53 * @v state Slave select state 54 * 55 * @c state must be @c SELECT_SLAVE or @c DESELECT_SLAVE. 56 */ 57 static void spi_bit_set_slave_select ( struct spi_bit_basher *spibit, 58 unsigned int slave, 59 unsigned int state ) { 60 struct bit_basher *basher = &spibit->basher; 61 62 state ^= ( spibit->bus.mode & SPI_MODE_SSPOL ); 63 DBGC2 ( spibit, "SPIBIT %p setting slave %d select %s\n", 64 spibit, slave, ( state ? "high" : "low" ) ); 65 66 spi_bit_delay(); 67 write_bit ( basher, SPI_BIT_SS ( slave ), state ); 68 spi_bit_delay(); 69 } 70 71 /** 72 * Transfer bits over SPI bit-bashing bus 73 * 74 * @v bus SPI bus 75 * @v data_out TX data buffer (or NULL) 76 * @v data_in RX data buffer (or NULL) 77 * @v len Length of transfer (in @b bits) 78 * @v endianness Endianness of this data transfer 79 * 80 * This issues @c len clock cycles on the SPI bus, shifting out data 81 * from the @c data_out buffer to the MOSI line and shifting in data 82 * from the MISO line to the @c data_in buffer. If @c data_out is 83 * NULL, then the data sent will be all zeroes. If @c data_in is 84 * NULL, then the incoming data will be discarded. 85 */ 86 static void spi_bit_transfer ( struct spi_bit_basher *spibit, 87 const void *data_out, void *data_in, 88 unsigned int len, int endianness ) { 89 struct spi_bus *bus = &spibit->bus; 90 struct bit_basher *basher = &spibit->basher; 91 unsigned int sclk = ( ( bus->mode & SPI_MODE_CPOL ) ? 1 : 0 ); 92 unsigned int cpha = ( ( bus->mode & SPI_MODE_CPHA ) ? 1 : 0 ); 93 unsigned int bit_offset; 94 unsigned int byte_offset; 95 unsigned int byte_mask; 96 unsigned int bit; 97 unsigned int step; 98 99 DBGC2 ( spibit, "SPIBIT %p transferring %d bits in mode %#x\n", 100 spibit, len, bus->mode ); 101 102 for ( step = 0 ; step < ( len * 2 ) ; step++ ) { 103 /* Calculate byte offset and byte mask */ 104 bit_offset = ( ( endianness == SPI_BIT_BIG_ENDIAN ) ? 105 ( len - ( step / 2 ) - 1 ) : ( step / 2 ) ); 106 byte_offset = ( bit_offset / 8 ); 107 byte_mask = ( 1 << ( bit_offset % 8 ) ); 108 109 /* Shift data in or out */ 110 if ( sclk == cpha ) { 111 const uint8_t *byte; 112 113 /* Shift data out */ 114 if ( data_out ) { 115 byte = ( data_out + byte_offset ); 116 bit = ( *byte & byte_mask ); 117 DBGCP ( spibit, "SPIBIT %p wrote bit %d\n", 118 spibit, ( bit ? 1 : 0 ) ); 119 } else { 120 bit = 0; 121 } 122 write_bit ( basher, SPI_BIT_MOSI, bit ); 123 } else { 124 uint8_t *byte; 125 126 /* Shift data in */ 127 bit = read_bit ( basher, SPI_BIT_MISO ); 128 if ( data_in ) { 129 DBGCP ( spibit, "SPIBIT %p read bit %d\n", 130 spibit, ( bit ? 1 : 0 ) ); 131 byte = ( data_in + byte_offset ); 132 *byte &= ~byte_mask; 133 *byte |= ( bit & byte_mask ); 134 } 135 } 136 137 /* Toggle clock line */ 138 spi_bit_delay(); 139 sclk ^= 1; 140 write_bit ( basher, SPI_BIT_SCLK, sclk ); 141 } 142 } 143 144 /** 145 * Read/write data via SPI bit-bashing bus 146 * 147 * @v bus SPI bus 148 * @v device SPI device 149 * @v command Command 150 * @v address Address to read/write (<0 for no address) 151 * @v data_out TX data buffer (or NULL) 152 * @v data_in RX data buffer (or NULL) 153 * @v len Length of transfer 154 * @ret rc Return status code 155 */ 156 static int spi_bit_rw ( struct spi_bus *bus, struct spi_device *device, 157 unsigned int command, int address, 158 const void *data_out, void *data_in, size_t len ) { 159 struct spi_bit_basher *spibit 160 = container_of ( bus, struct spi_bit_basher, bus ); 161 uint32_t tmp_command; 162 uint32_t tmp_address; 163 uint32_t tmp_address_detect; 164 165 /* Set clock line to idle state */ 166 write_bit ( &spibit->basher, SPI_BIT_SCLK, 167 ( bus->mode & SPI_MODE_CPOL ) ); 168 169 /* Assert chip select on specified slave */ 170 spi_bit_set_slave_select ( spibit, device->slave, SELECT_SLAVE ); 171 172 /* Transmit command */ 173 assert ( device->command_len <= ( 8 * sizeof ( tmp_command ) ) ); 174 tmp_command = cpu_to_le32 ( command ); 175 spi_bit_transfer ( spibit, &tmp_command, NULL, device->command_len, 176 SPI_BIT_BIG_ENDIAN ); 177 178 /* Transmit address, if present */ 179 if ( address >= 0 ) { 180 assert ( device->address_len <= ( 8 * sizeof ( tmp_address ))); 181 tmp_address = cpu_to_le32 ( address ); 182 if ( device->address_len == SPI_AUTODETECT_ADDRESS_LEN ) { 183 /* Autodetect address length. This relies on 184 * the device responding with a dummy zero 185 * data bit before the first real data bit. 186 */ 187 DBGC ( spibit, "SPIBIT %p autodetecting device " 188 "address length\n", spibit ); 189 assert ( address == 0 ); 190 device->address_len = 0; 191 do { 192 spi_bit_transfer ( spibit, &tmp_address, 193 &tmp_address_detect, 1, 194 SPI_BIT_BIG_ENDIAN ); 195 device->address_len++; 196 } while ( le32_to_cpu ( tmp_address_detect ) & 1 ); 197 DBGC ( spibit, "SPIBIT %p autodetected device address " 198 "length %d\n", spibit, device->address_len ); 199 } else { 200 spi_bit_transfer ( spibit, &tmp_address, NULL, 201 device->address_len, 202 SPI_BIT_BIG_ENDIAN ); 203 } 204 } 205 206 /* Transmit/receive data */ 207 spi_bit_transfer ( spibit, data_out, data_in, ( len * 8 ), 208 spibit->endianness ); 209 210 /* Deassert chip select on specified slave */ 211 spi_bit_set_slave_select ( spibit, device->slave, DESELECT_SLAVE ); 212 213 return 0; 214 } 215 216 /** 217 * Initialise SPI bit-bashing interface 218 * 219 * @v spibit SPI bit-bashing interface 220 */ 221 void init_spi_bit_basher ( struct spi_bit_basher *spibit ) { 222 assert ( &spibit->basher.op->read != NULL ); 223 assert ( &spibit->basher.op->write != NULL ); 224 spibit->bus.rw = spi_bit_rw; 225 } 226