diff options
author | Cory Maccarrone <darkstar6262@gmail.com> | 2010-05-29 20:12:23 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-07-04 00:45:44 -0400 |
commit | 5c2818cdfad1973ede3dcd2a8709620a192f8385 (patch) | |
tree | c23de1403063aaff5e489636bee97ef7715514a8 /drivers/spi | |
parent | 4751c1c74bc7b596db5de0c93be1a22a570145c0 (diff) |
SPI100k: Fix 8-bit and RX-only transfers
This change fixes 8-bit transfers and RX-only transfers. The
SPI100k framework requires minimum 16-bit words to be written, so 8-bit
transfers must be shited by 8 bits and sent out as a 16-bit word.
Additionally, receive-only transfers were failing due to the
perceived need to fill the TX buffer with something. This is in
fact not needed.
Signed-off-by: Cory Maccarrone <darkstar6262@gmail.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/omap_spi_100k.c | 23 |
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/spi/omap_spi_100k.c b/drivers/spi/omap_spi_100k.c index 24668b30a52d..9bd1c92ad96e 100644 --- a/drivers/spi/omap_spi_100k.c +++ b/drivers/spi/omap_spi_100k.c | |||
@@ -141,7 +141,12 @@ static void spi100k_write_data(struct spi_master *master, int len, int data) | |||
141 | { | 141 | { |
142 | struct omap1_spi100k *spi100k = spi_master_get_devdata(master); | 142 | struct omap1_spi100k *spi100k = spi_master_get_devdata(master); |
143 | 143 | ||
144 | /* write 16-bit word */ | 144 | /* write 16-bit word, shifting 8-bit data if necessary */ |
145 | if (len <= 8) { | ||
146 | data <<= 8; | ||
147 | len = 16; | ||
148 | } | ||
149 | |||
145 | spi100k_enable_clock(master); | 150 | spi100k_enable_clock(master); |
146 | writew( data , spi100k->base + SPI_TX_MSB); | 151 | writew( data , spi100k->base + SPI_TX_MSB); |
147 | 152 | ||
@@ -162,6 +167,10 @@ static int spi100k_read_data(struct spi_master *master, int len) | |||
162 | int dataH,dataL; | 167 | int dataH,dataL; |
163 | struct omap1_spi100k *spi100k = spi_master_get_devdata(master); | 168 | struct omap1_spi100k *spi100k = spi_master_get_devdata(master); |
164 | 169 | ||
170 | /* Always do at least 16 bits */ | ||
171 | if (len <= 8) | ||
172 | len = 16; | ||
173 | |||
165 | spi100k_enable_clock(master); | 174 | spi100k_enable_clock(master); |
166 | writew(SPI_CTRL_SEN(0) | | 175 | writew(SPI_CTRL_SEN(0) | |
167 | SPI_CTRL_WORD_SIZE(len) | | 176 | SPI_CTRL_WORD_SIZE(len) | |
@@ -214,10 +223,6 @@ omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
214 | c = count; | 223 | c = count; |
215 | word_len = cs->word_len; | 224 | word_len = cs->word_len; |
216 | 225 | ||
217 | /* RX_ONLY mode needs dummy data in TX reg */ | ||
218 | if (xfer->tx_buf == NULL) | ||
219 | spi100k_write_data(spi->master,word_len, 0); | ||
220 | |||
221 | if (word_len <= 8) { | 226 | if (word_len <= 8) { |
222 | u8 *rx; | 227 | u8 *rx; |
223 | const u8 *tx; | 228 | const u8 *tx; |
@@ -227,9 +232,9 @@ omap1_spi100k_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
227 | do { | 232 | do { |
228 | c-=1; | 233 | c-=1; |
229 | if (xfer->tx_buf != NULL) | 234 | if (xfer->tx_buf != NULL) |
230 | spi100k_write_data(spi->master,word_len, *tx); | 235 | spi100k_write_data(spi->master, word_len, *tx++); |
231 | if (xfer->rx_buf != NULL) | 236 | if (xfer->rx_buf != NULL) |
232 | *rx = spi100k_read_data(spi->master,word_len); | 237 | *rx++ = spi100k_read_data(spi->master, word_len); |
233 | } while(c); | 238 | } while(c); |
234 | } else if (word_len <= 16) { | 239 | } else if (word_len <= 16) { |
235 | u16 *rx; | 240 | u16 *rx; |
@@ -380,10 +385,6 @@ static void omap1_spi100k_work(struct work_struct *work) | |||
380 | if (t->len) { | 385 | if (t->len) { |
381 | unsigned count; | 386 | unsigned count; |
382 | 387 | ||
383 | /* RX_ONLY mode needs dummy data in TX reg */ | ||
384 | if (t->tx_buf == NULL) | ||
385 | spi100k_write_data(spi->master, 8, 0); | ||
386 | |||
387 | count = omap1_spi100k_txrx_pio(spi, t); | 388 | count = omap1_spi100k_txrx_pio(spi, t); |
388 | m->actual_length += count; | 389 | m->actual_length += count; |
389 | 390 | ||