aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorCory Maccarrone <darkstar6262@gmail.com>2010-05-29 20:12:23 -0400
committerGrant Likely <grant.likely@secretlab.ca>2010-07-04 00:45:44 -0400
commit5c2818cdfad1973ede3dcd2a8709620a192f8385 (patch)
treec23de1403063aaff5e489636bee97ef7715514a8 /drivers/spi
parent4751c1c74bc7b596db5de0c93be1a22a570145c0 (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.c23
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