#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <byteswap.h>
#include <errno.h>
#include <assert.h>
#include <unistd.h>
#include <gpxe/bitbash.h>
#include <gpxe/spi_bit.h>
Go to the source code of this file.
Defines | |
| #define | SELECT_SLAVE 0 |
| Chip select line will be asserted. | |
| #define | DESELECT_SLAVE SPI_MODE_SSPOL |
| Chip select line will be deasserted. | |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static void | spi_bit_delay (void) |
| Delay between SCLK changes and around SS changes. | |
| static void | spi_bit_set_slave_select (struct spi_bit_basher *spibit, unsigned int slave, unsigned int state) |
| Select/deselect slave. | |
| static void | spi_bit_transfer (struct spi_bit_basher *spibit, const void *data_out, void *data_in, unsigned int len, int endianness) |
| Transfer bits over SPI bit-bashing bus. | |
| static int | spi_bit_rw (struct spi_bus *bus, struct spi_device *device, unsigned int command, int address, const void *data_out, void *data_in, size_t len) |
| Read/write data via SPI bit-bashing bus. | |
| void | init_spi_bit_basher (struct spi_bit_basher *spibit) |
| Initialise SPI bit-bashing interface. | |
Definition in file spi_bit.c.
| #define SELECT_SLAVE 0 |
Chip select line will be asserted.
Definition at line 43 of file spi_bit.c.
Referenced by spi_bit_rw().
| #define DESELECT_SLAVE SPI_MODE_SSPOL |
Chip select line will be deasserted.
Definition at line 46 of file spi_bit.c.
Referenced by spi_bit_rw().
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static void spi_bit_delay | ( | void | ) | [static] |
Delay between SCLK changes and around SS changes.
Definition at line 38 of file spi_bit.c.
References SPI_BIT_UDELAY, and udelay().
Referenced by spi_bit_set_slave_select(), and spi_bit_transfer().
00038 { 00039 udelay ( SPI_BIT_UDELAY ); 00040 }
| static void spi_bit_set_slave_select | ( | struct spi_bit_basher * | spibit, | |
| unsigned int | slave, | |||
| unsigned int | state | |||
| ) | [static] |
Select/deselect slave.
| spibit | SPI bit-bashing interface | |
| slave | Slave number | |
| state | Slave select state |
state must be SELECT_SLAVE or DESELECT_SLAVE.
Definition at line 57 of file spi_bit.c.
References spi_bit_basher::basher, spi_bit_basher::bus, DBGC2, spi_bus::mode, spi_bit_delay(), SPI_BIT_SS, SPI_MODE_SSPOL, and write_bit().
Referenced by spi_bit_rw().
00059 { 00060 struct bit_basher *basher = &spibit->basher; 00061 00062 state ^= ( spibit->bus.mode & SPI_MODE_SSPOL ); 00063 DBGC2 ( spibit, "SPIBIT %p setting slave %d select %s\n", 00064 spibit, slave, ( state ? "high" : "low" ) ); 00065 00066 spi_bit_delay(); 00067 write_bit ( basher, SPI_BIT_SS ( slave ), state ); 00068 spi_bit_delay(); 00069 }
| static void spi_bit_transfer | ( | struct spi_bit_basher * | spibit, | |
| const void * | data_out, | |||
| void * | data_in, | |||
| unsigned int | len, | |||
| int | endianness | |||
| ) | [static] |
Transfer bits over SPI bit-bashing bus.
| bus | SPI bus | |
| data_out | TX data buffer (or NULL) | |
| data_in | RX data buffer (or NULL) | |
| len | Length of transfer (in bits) | |
| endianness | Endianness of this data transfer |
len clock cycles on the SPI bus, shifting out data from the data_out buffer to the MOSI line and shifting in data from the MISO line to the data_in buffer. If data_out is NULL, then the data sent will be all zeroes. If data_in is NULL, then the incoming data will be discarded.
Definition at line 86 of file spi_bit.c.
References spi_bit_basher::basher, spi_bit_basher::bus, DBGC2, DBGCP, spi_bus::mode, read_bit(), SPI_BIT_BIG_ENDIAN, spi_bit_delay(), SPI_BIT_MISO, SPI_BIT_MOSI, SPI_BIT_SCLK, SPI_MODE_CPHA, SPI_MODE_CPOL, step(), and write_bit().
Referenced by spi_bit_rw().
00088 { 00089 struct spi_bus *bus = &spibit->bus; 00090 struct bit_basher *basher = &spibit->basher; 00091 unsigned int sclk = ( ( bus->mode & SPI_MODE_CPOL ) ? 1 : 0 ); 00092 unsigned int cpha = ( ( bus->mode & SPI_MODE_CPHA ) ? 1 : 0 ); 00093 unsigned int bit_offset; 00094 unsigned int byte_offset; 00095 unsigned int byte_mask; 00096 unsigned int bit; 00097 unsigned int step; 00098 00099 DBGC2 ( spibit, "SPIBIT %p transferring %d bits in mode %#x\n", 00100 spibit, len, bus->mode ); 00101 00102 for ( step = 0 ; step < ( len * 2 ) ; step++ ) { 00103 /* Calculate byte offset and byte mask */ 00104 bit_offset = ( ( endianness == SPI_BIT_BIG_ENDIAN ) ? 00105 ( len - ( step / 2 ) - 1 ) : ( step / 2 ) ); 00106 byte_offset = ( bit_offset / 8 ); 00107 byte_mask = ( 1 << ( bit_offset % 8 ) ); 00108 00109 /* Shift data in or out */ 00110 if ( sclk == cpha ) { 00111 const uint8_t *byte; 00112 00113 /* Shift data out */ 00114 if ( data_out ) { 00115 byte = ( data_out + byte_offset ); 00116 bit = ( *byte & byte_mask ); 00117 DBGCP ( spibit, "SPIBIT %p wrote bit %d\n", 00118 spibit, ( bit ? 1 : 0 ) ); 00119 } else { 00120 bit = 0; 00121 } 00122 write_bit ( basher, SPI_BIT_MOSI, bit ); 00123 } else { 00124 uint8_t *byte; 00125 00126 /* Shift data in */ 00127 bit = read_bit ( basher, SPI_BIT_MISO ); 00128 if ( data_in ) { 00129 DBGCP ( spibit, "SPIBIT %p read bit %d\n", 00130 spibit, ( bit ? 1 : 0 ) ); 00131 byte = ( data_in + byte_offset ); 00132 *byte &= ~byte_mask; 00133 *byte |= ( bit & byte_mask ); 00134 } 00135 } 00136 00137 /* Toggle clock line */ 00138 spi_bit_delay(); 00139 sclk ^= 1; 00140 write_bit ( basher, SPI_BIT_SCLK, sclk ); 00141 } 00142 }
| static int spi_bit_rw | ( | struct spi_bus * | bus, | |
| struct spi_device * | device, | |||
| unsigned int | command, | |||
| int | address, | |||
| const void * | data_out, | |||
| void * | data_in, | |||
| size_t | len | |||
| ) | [static] |
Read/write data via SPI bit-bashing bus.
| bus | SPI bus | |
| device | SPI device | |
| command | Command | |
| address | Address to read/write (<0 for no address) | |
| data_out | TX data buffer (or NULL) | |
| data_in | RX data buffer (or NULL) | |
| len | Length of transfer |
| rc | Return status code |
Definition at line 156 of file spi_bit.c.
References spi_device::address_len, assert, spi_bit_basher::basher, spi_device::command_len, container_of, cpu_to_le32, DBGC, DESELECT_SLAVE, spi_bit_basher::endianness, le32_to_cpu, spi_bus::mode, NULL, SELECT_SLAVE, spi_device::slave, SPI_AUTODETECT_ADDRESS_LEN, SPI_BIT_BIG_ENDIAN, SPI_BIT_SCLK, spi_bit_set_slave_select(), spi_bit_transfer(), SPI_MODE_CPOL, and write_bit().
Referenced by init_spi_bit_basher().
00158 { 00159 struct spi_bit_basher *spibit 00160 = container_of ( bus, struct spi_bit_basher, bus ); 00161 uint32_t tmp_command; 00162 uint32_t tmp_address; 00163 uint32_t tmp_address_detect; 00164 00165 /* Set clock line to idle state */ 00166 write_bit ( &spibit->basher, SPI_BIT_SCLK, 00167 ( bus->mode & SPI_MODE_CPOL ) ); 00168 00169 /* Assert chip select on specified slave */ 00170 spi_bit_set_slave_select ( spibit, device->slave, SELECT_SLAVE ); 00171 00172 /* Transmit command */ 00173 assert ( device->command_len <= ( 8 * sizeof ( tmp_command ) ) ); 00174 tmp_command = cpu_to_le32 ( command ); 00175 spi_bit_transfer ( spibit, &tmp_command, NULL, device->command_len, 00176 SPI_BIT_BIG_ENDIAN ); 00177 00178 /* Transmit address, if present */ 00179 if ( address >= 0 ) { 00180 assert ( device->address_len <= ( 8 * sizeof ( tmp_address ))); 00181 tmp_address = cpu_to_le32 ( address ); 00182 if ( device->address_len == SPI_AUTODETECT_ADDRESS_LEN ) { 00183 /* Autodetect address length. This relies on 00184 * the device responding with a dummy zero 00185 * data bit before the first real data bit. 00186 */ 00187 DBGC ( spibit, "SPIBIT %p autodetecting device " 00188 "address length\n", spibit ); 00189 assert ( address == 0 ); 00190 device->address_len = 0; 00191 do { 00192 spi_bit_transfer ( spibit, &tmp_address, 00193 &tmp_address_detect, 1, 00194 SPI_BIT_BIG_ENDIAN ); 00195 device->address_len++; 00196 } while ( le32_to_cpu ( tmp_address_detect ) & 1 ); 00197 DBGC ( spibit, "SPIBIT %p autodetected device address " 00198 "length %d\n", spibit, device->address_len ); 00199 } else { 00200 spi_bit_transfer ( spibit, &tmp_address, NULL, 00201 device->address_len, 00202 SPI_BIT_BIG_ENDIAN ); 00203 } 00204 } 00205 00206 /* Transmit/receive data */ 00207 spi_bit_transfer ( spibit, data_out, data_in, ( len * 8 ), 00208 spibit->endianness ); 00209 00210 /* Deassert chip select on specified slave */ 00211 spi_bit_set_slave_select ( spibit, device->slave, DESELECT_SLAVE ); 00212 00213 return 0; 00214 }
| void init_spi_bit_basher | ( | struct spi_bit_basher * | spibit | ) |
Initialise SPI bit-bashing interface.
| spibit | SPI bit-bashing interface |
Definition at line 221 of file spi_bit.c.
References assert, spi_bit_basher::basher, spi_bit_basher::bus, NULL, bit_basher::op, bit_basher_operations::read, spi_bus::rw, spi_bit_rw(), and bit_basher_operations::write.
Referenced by ifec_init_eeprom(), natsemi_init_eeprom(), rtl818x_probe(), and rtl_init_eeprom().
00221 { 00222 assert ( &spibit->basher.op->read != NULL ); 00223 assert ( &spibit->basher.op->write != NULL ); 00224 spibit->bus.rw = spi_bit_rw; 00225 }
1.5.7.1