aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorJoakim Tjernlund <Joakim.Tjernlund@transmode.se>2010-05-14 05:14:26 -0400
committerGrant Likely <grant.likely@secretlab.ca>2010-05-25 02:17:51 -0400
commit0398fb70940e1f10939d6126eafb760bd48d1566 (patch)
treefabaaf8936b0e68ec058192cc155640672919694 /drivers/spi
parentf9218c2a60facc6ff9a793a9d9ab956194d70012 (diff)
spi/spi_mpc8xxx: Fix QE mode Litte Endian
QE mode uses Little Endian so words > 8 bits are byte swapped. Workaround this by always enforcing wordsize 8 for words > 8 bits. Unfortunately this will not work for LSB transfers where wordsize is > 8 bits so disable these for now. Also move the different quirks into its own function to keep mpc8xxx_spi_setup_transfer() sane. Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se> Acked-by: Anton Vorontsov <cbouatmailru@gmail.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi_mpc8xxx.c101
1 files changed, 70 insertions, 31 deletions
diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c
index 0dfc482bbff5..66517ce750f3 100644
--- a/drivers/spi/spi_mpc8xxx.c
+++ b/drivers/spi/spi_mpc8xxx.c
@@ -286,36 +286,12 @@ static void mpc8xxx_spi_chipselect(struct spi_device *spi, int value)
286 } 286 }
287} 287}
288 288
289static 289static int
290int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) 290mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs,
291 struct spi_device *spi,
292 struct mpc8xxx_spi *mpc8xxx_spi,
293 int bits_per_word)
291{ 294{
292 struct mpc8xxx_spi *mpc8xxx_spi;
293 u8 bits_per_word, pm;
294 u32 hz;
295 struct spi_mpc8xxx_cs *cs = spi->controller_state;
296
297 mpc8xxx_spi = spi_master_get_devdata(spi->master);
298
299 if (t) {
300 bits_per_word = t->bits_per_word;
301 hz = t->speed_hz;
302 } else {
303 bits_per_word = 0;
304 hz = 0;
305 }
306
307 /* spi_transfer level calls that work per-word */
308 if (!bits_per_word)
309 bits_per_word = spi->bits_per_word;
310
311 /* Make sure its a bit width we support [4..16, 32] */
312 if ((bits_per_word < 4)
313 || ((bits_per_word > 16) && (bits_per_word != 32)))
314 return -EINVAL;
315
316 if (!hz)
317 hz = spi->max_speed_hz;
318
319 cs->rx_shift = 0; 295 cs->rx_shift = 0;
320 cs->tx_shift = 0; 296 cs->tx_shift = 0;
321 if (bits_per_word <= 8) { 297 if (bits_per_word <= 8) {
@@ -339,19 +315,82 @@ int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
339 return -EINVAL; 315 return -EINVAL;
340 316
341 if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE && 317 if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE &&
342 spi->mode & SPI_LSB_FIRST) { 318 spi->mode & SPI_LSB_FIRST) {
343 cs->tx_shift = 0; 319 cs->tx_shift = 0;
344 if (bits_per_word <= 8) 320 if (bits_per_word <= 8)
345 cs->rx_shift = 8; 321 cs->rx_shift = 8;
346 else 322 else
347 cs->rx_shift = 0; 323 cs->rx_shift = 0;
348 } 324 }
349
350 mpc8xxx_spi->rx_shift = cs->rx_shift; 325 mpc8xxx_spi->rx_shift = cs->rx_shift;
351 mpc8xxx_spi->tx_shift = cs->tx_shift; 326 mpc8xxx_spi->tx_shift = cs->tx_shift;
352 mpc8xxx_spi->get_rx = cs->get_rx; 327 mpc8xxx_spi->get_rx = cs->get_rx;
353 mpc8xxx_spi->get_tx = cs->get_tx; 328 mpc8xxx_spi->get_tx = cs->get_tx;
354 329
330 return bits_per_word;
331}
332
333static int
334mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs,
335 struct spi_device *spi,
336 int bits_per_word)
337{
338 /* QE uses Little Endian for words > 8
339 * so transform all words > 8 into 8 bits
340 * Unfortnatly that doesn't work for LSB so
341 * reject these for now */
342 /* Note: 32 bits word, LSB works iff
343 * tfcr/rfcr is set to CPMFCR_GBL */
344 if (spi->mode & SPI_LSB_FIRST &&
345 bits_per_word > 8)
346 return -EINVAL;
347 if (bits_per_word > 8)
348 return 8; /* pretend its 8 bits */
349 return bits_per_word;
350}
351
352static
353int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
354{
355 struct mpc8xxx_spi *mpc8xxx_spi;
356 int bits_per_word;
357 u8 pm;
358 u32 hz;
359 struct spi_mpc8xxx_cs *cs = spi->controller_state;
360
361 mpc8xxx_spi = spi_master_get_devdata(spi->master);
362
363 if (t) {
364 bits_per_word = t->bits_per_word;
365 hz = t->speed_hz;
366 } else {
367 bits_per_word = 0;
368 hz = 0;
369 }
370
371 /* spi_transfer level calls that work per-word */
372 if (!bits_per_word)
373 bits_per_word = spi->bits_per_word;
374
375 /* Make sure its a bit width we support [4..16, 32] */
376 if ((bits_per_word < 4)
377 || ((bits_per_word > 16) && (bits_per_word != 32)))
378 return -EINVAL;
379
380 if (!hz)
381 hz = spi->max_speed_hz;
382
383 if (!(mpc8xxx_spi->flags & SPI_CPM_MODE))
384 bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi,
385 mpc8xxx_spi,
386 bits_per_word);
387 else if (mpc8xxx_spi->flags & SPI_QE)
388 bits_per_word = mspi_apply_qe_mode_quirks(cs, spi,
389 bits_per_word);
390
391 if (bits_per_word < 0)
392 return bits_per_word;
393
355 if (bits_per_word == 32) 394 if (bits_per_word == 32)
356 bits_per_word = 0; 395 bits_per_word = 0;
357 else 396 else