|
|
1.1 root 1: /*
2: * Copyright (C) 2006 Michael Brown <[email protected]>.
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 <ipxe/bitbash.h>
29: #include <ipxe/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: /* Deassert chip select to reset specified slave */
166: spi_bit_set_slave_select ( spibit, device->slave, DESELECT_SLAVE );
167:
168: /* Set clock line to idle state */
169: write_bit ( &spibit->basher, SPI_BIT_SCLK,
170: ( bus->mode & SPI_MODE_CPOL ) );
171:
172: /* Assert chip select on specified slave */
173: spi_bit_set_slave_select ( spibit, device->slave, SELECT_SLAVE );
174:
175: /* Transmit command */
176: assert ( device->command_len <= ( 8 * sizeof ( tmp_command ) ) );
177: tmp_command = cpu_to_le32 ( command );
178: spi_bit_transfer ( spibit, &tmp_command, NULL, device->command_len,
179: SPI_BIT_BIG_ENDIAN );
180:
181: /* Transmit address, if present */
182: if ( address >= 0 ) {
183: assert ( device->address_len <= ( 8 * sizeof ( tmp_address )));
184: tmp_address = cpu_to_le32 ( address );
185: if ( device->address_len == SPI_AUTODETECT_ADDRESS_LEN ) {
186: /* Autodetect address length. This relies on
187: * the device responding with a dummy zero
188: * data bit before the first real data bit.
189: */
190: DBGC ( spibit, "SPIBIT %p autodetecting device "
191: "address length\n", spibit );
192: assert ( address == 0 );
193: device->address_len = 0;
194: do {
195: spi_bit_transfer ( spibit, &tmp_address,
196: &tmp_address_detect, 1,
197: SPI_BIT_BIG_ENDIAN );
198: device->address_len++;
199: } while ( le32_to_cpu ( tmp_address_detect ) & 1 );
200: DBGC ( spibit, "SPIBIT %p autodetected device address "
201: "length %d\n", spibit, device->address_len );
202: } else {
203: spi_bit_transfer ( spibit, &tmp_address, NULL,
204: device->address_len,
205: SPI_BIT_BIG_ENDIAN );
206: }
207: }
208:
209: /* Transmit/receive data */
210: spi_bit_transfer ( spibit, data_out, data_in, ( len * 8 ),
211: spibit->endianness );
212:
213: /* Deassert chip select on specified slave */
214: spi_bit_set_slave_select ( spibit, device->slave, DESELECT_SLAVE );
215:
216: return 0;
217: }
218:
219: /**
220: * Initialise SPI bit-bashing interface
221: *
222: * @v spibit SPI bit-bashing interface
223: */
224: void init_spi_bit_basher ( struct spi_bit_basher *spibit ) {
225: assert ( &spibit->basher.op->read != NULL );
226: assert ( &spibit->basher.op->write != NULL );
227: spibit->bus.rw = spi_bit_rw;
228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.