00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <stddef.h>
00022 #include <stdint.h>
00023 #include <string.h>
00024 #include <byteswap.h>
00025 #include <errno.h>
00026 #include <assert.h>
00027 #include <unistd.h>
00028 #include <gpxe/bitbash.h>
00029 #include <gpxe/spi_bit.h>
00030
00031
00032
00033
00034
00035
00036
00037
00038 static void spi_bit_delay ( void ) {
00039 udelay ( SPI_BIT_UDELAY );
00040 }
00041
00042
00043 #define SELECT_SLAVE 0
00044
00045
00046 #define DESELECT_SLAVE SPI_MODE_SSPOL
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 static void spi_bit_set_slave_select ( struct spi_bit_basher *spibit,
00058 unsigned int slave,
00059 unsigned int state ) {
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 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 static void spi_bit_transfer ( struct spi_bit_basher *spibit,
00087 const void *data_out, void *data_in,
00088 unsigned int len, int endianness ) {
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
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
00110 if ( sclk == cpha ) {
00111 const uint8_t *byte;
00112
00113
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
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
00138 spi_bit_delay();
00139 sclk ^= 1;
00140 write_bit ( basher, SPI_BIT_SCLK, sclk );
00141 }
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 static int spi_bit_rw ( struct spi_bus *bus, struct spi_device *device,
00157 unsigned int command, int address,
00158 const void *data_out, void *data_in, size_t len ) {
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
00166 write_bit ( &spibit->basher, SPI_BIT_SCLK,
00167 ( bus->mode & SPI_MODE_CPOL ) );
00168
00169
00170 spi_bit_set_slave_select ( spibit, device->slave, SELECT_SLAVE );
00171
00172
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
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
00184
00185
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
00207 spi_bit_transfer ( spibit, data_out, data_in, ( len * 8 ),
00208 spibit->endianness );
00209
00210
00211 spi_bit_set_slave_select ( spibit, device->slave, DESELECT_SLAVE );
00212
00213 return 0;
00214 }
00215
00216
00217
00218
00219
00220
00221 void init_spi_bit_basher ( struct spi_bit_basher *spibit ) {
00222 assert ( &spibit->basher.op->read != NULL );
00223 assert ( &spibit->basher.op->write != NULL );
00224 spibit->bus.rw = spi_bit_rw;
00225 }