diff options
| -rw-r--r-- | drivers/spi/spi_mpc8xxx.c | 101 |
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 | ||
| 289 | static | 289 | static int |
| 290 | int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | 290 | mspi_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 | |||
| 333 | static int | ||
| 334 | mspi_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 | |||
| 352 | static | ||
| 353 | int 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 |
