reg &= ~MT7621_LSB_FIRST; if (spi->mode & SPI_LSB_FIRST)
reg |= MT7621_LSB_FIRST;
/* * This SPI controller seems to be tested on SPI flash only and some * bits are swizzled under other SPI modes probably due to incorrect * wiring inside the silicon. Only mode 0 works correctly.
*/
reg &= ~(MT7621_CPHA | MT7621_CPOL);
mt7621_spi_write(rs, MT7621_SPI_MASTER, reg);
return 0;
}
staticinlineint mt7621_spi_wait_till_ready(struct mt7621_spi *rs)
{ int i;
for (i = 0; i < RALINK_SPI_WAIT_MAX_LOOP; i++) {
u32 status;
status = mt7621_spi_read(rs, MT7621_SPI_TRANS); if ((status & SPITRANS_BUSY) == 0) return 0;
cpu_relax();
udelay(1);
}
list_for_each_entry(t, &m->transfers, transfer_list) if (t->speed_hz < speed)
speed = t->speed_hz;
return mt7621_spi_prepare(spi, speed);
}
staticvoid mt7621_spi_read_half_duplex(struct mt7621_spi *rs, int rx_len, u8 *buf)
{ int tx_len;
/* * Combine with any pending write, and perform one or more half-duplex * transactions reading 'len' bytes. Data to be written is already in * MT7621_SPI_DATA.
*/
tx_len = rs->pending_write;
rs->pending_write = 0;
while (rx_len || tx_len) { int i;
u32 val = (min(tx_len, 4) * 8) << 24; int rx = min(rx_len, 32);
if (tx_len > 4)
val |= (tx_len - 4) * 8;
val |= (rx * 8) << 12;
mt7621_spi_write(rs, MT7621_SPI_MOREBUF, val);
tx_len = 0;
val = mt7621_spi_read(rs, MT7621_SPI_TRANS);
val |= SPI_CTL_START;
mt7621_spi_write(rs, MT7621_SPI_TRANS, val);
mt7621_spi_wait_till_ready(rs);
for (i = 0; i < rx; i++) { if ((i % 4) == 0)
val = mt7621_spi_read(rs, MT7621_SPI_DATA0 + i);
*buf++ = val & 0xff;
val >>= 8;
}
staticvoid mt7621_spi_write_half_duplex(struct mt7621_spi *rs, int tx_len, const u8 *buf)
{ int len = rs->pending_write; int val = 0;
if (len & 3) {
val = mt7621_spi_read(rs, MT7621_SPI_OPCODE + (len & ~3)); if (len < 4) {
val <<= (4 - len) * 8;
val = swab32(val);
}
}
while (tx_len > 0) { if (len >= 36) {
rs->pending_write = len;
mt7621_spi_flush(rs);
len = 0;
}
val |= *buf++ << (8 * (len & 3));
len++; if ((len & 3) == 0) { if (len == 4) /* The byte-order of the opcode is weird! */
val = swab32(val);
mt7621_spi_write(rs, MT7621_SPI_OPCODE + len - 4, val);
val = 0;
}
tx_len -= 1;
}
if (len & 3) { if (len < 4) {
val = swab32(val);
val >>= (4 - len) * 8;
}
mt7621_spi_write(rs, MT7621_SPI_OPCODE + (len & ~3), val);
}
if ((t->rx_buf) && (t->tx_buf)) { /* * This controller will shift some extra data out * of spi_opcode if (mosi_bit_cnt > 0) && * (cmd_bit_cnt == 0). So the claimed full-duplex * support is broken since we have no way to read * the MISO value during that bit.
*/ return -EIO;
} elseif (t->rx_buf) {
mt7621_spi_read_half_duplex(rs, t->len, t->rx_buf);
} elseif (t->tx_buf) {
mt7621_spi_write_half_duplex(rs, t->len, t->tx_buf);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.