aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi_mpc83xx.c32
-rw-r--r--include/linux/fsl_devices.h2
2 files changed, 30 insertions, 4 deletions
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index bbd51bc88a60..3295cfcc9f20 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -47,6 +47,7 @@ struct mpc83xx_spi_reg {
47#define SPMODE_ENABLE (1 << 24) 47#define SPMODE_ENABLE (1 << 24)
48#define SPMODE_LEN(x) ((x) << 20) 48#define SPMODE_LEN(x) ((x) << 20)
49#define SPMODE_PM(x) ((x) << 16) 49#define SPMODE_PM(x) ((x) << 16)
50#define SPMODE_OP (1 << 14)
50 51
51/* 52/*
52 * Default for SPI Mode: 53 * Default for SPI Mode:
@@ -85,6 +86,11 @@ struct mpc83xx_spi {
85 unsigned nsecs; /* (clock cycle time)/2 */ 86 unsigned nsecs; /* (clock cycle time)/2 */
86 87
87 u32 sysclk; 88 u32 sysclk;
89 u32 rx_shift; /* RX data reg shift when in qe mode */
90 u32 tx_shift; /* TX data reg shift when in qe mode */
91
92 bool qe_mode;
93
88 void (*activate_cs) (u8 cs, u8 polarity); 94 void (*activate_cs) (u8 cs, u8 polarity);
89 void (*deactivate_cs) (u8 cs, u8 polarity); 95 void (*deactivate_cs) (u8 cs, u8 polarity);
90}; 96};
@@ -103,7 +109,7 @@ static inline u32 mpc83xx_spi_read_reg(__be32 __iomem * reg)
103void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \ 109void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \
104{ \ 110{ \
105 type * rx = mpc83xx_spi->rx; \ 111 type * rx = mpc83xx_spi->rx; \
106 *rx++ = (type)data; \ 112 *rx++ = (type)(data >> mpc83xx_spi->rx_shift); \
107 mpc83xx_spi->rx = rx; \ 113 mpc83xx_spi->rx = rx; \
108} 114}
109 115
@@ -114,7 +120,7 @@ u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi) \
114 const type * tx = mpc83xx_spi->tx; \ 120 const type * tx = mpc83xx_spi->tx; \
115 if (!tx) \ 121 if (!tx) \
116 return 0; \ 122 return 0; \
117 data = *tx++; \ 123 data = *tx++ << mpc83xx_spi->tx_shift; \
118 mpc83xx_spi->tx = tx; \ 124 mpc83xx_spi->tx = tx; \
119 return data; \ 125 return data; \
120} 126}
@@ -203,12 +209,22 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
203 || ((bits_per_word > 16) && (bits_per_word != 32))) 209 || ((bits_per_word > 16) && (bits_per_word != 32)))
204 return -EINVAL; 210 return -EINVAL;
205 211
212 mpc83xx_spi->rx_shift = 0;
213 mpc83xx_spi->tx_shift = 0;
206 if (bits_per_word <= 8) { 214 if (bits_per_word <= 8) {
207 mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; 215 mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
208 mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; 216 mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
217 if (mpc83xx_spi->qe_mode) {
218 mpc83xx_spi->rx_shift = 16;
219 mpc83xx_spi->tx_shift = 24;
220 }
209 } else if (bits_per_word <= 16) { 221 } else if (bits_per_word <= 16) {
210 mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16; 222 mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16;
211 mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16; 223 mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16;
224 if (mpc83xx_spi->qe_mode) {
225 mpc83xx_spi->rx_shift = 16;
226 mpc83xx_spi->tx_shift = 16;
227 }
212 } else if (bits_per_word <= 32) { 228 } else if (bits_per_word <= 32) {
213 mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32; 229 mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32;
214 mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32; 230 mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32;
@@ -386,7 +402,6 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
386 ret = -ENODEV; 402 ret = -ENODEV;
387 goto free_master; 403 goto free_master;
388 } 404 }
389
390 mpc83xx_spi = spi_master_get_devdata(master); 405 mpc83xx_spi = spi_master_get_devdata(master);
391 mpc83xx_spi->bitbang.master = spi_master_get(master); 406 mpc83xx_spi->bitbang.master = spi_master_get(master);
392 mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect; 407 mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect;
@@ -395,9 +410,17 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
395 mpc83xx_spi->sysclk = pdata->sysclk; 410 mpc83xx_spi->sysclk = pdata->sysclk;
396 mpc83xx_spi->activate_cs = pdata->activate_cs; 411 mpc83xx_spi->activate_cs = pdata->activate_cs;
397 mpc83xx_spi->deactivate_cs = pdata->deactivate_cs; 412 mpc83xx_spi->deactivate_cs = pdata->deactivate_cs;
413 mpc83xx_spi->qe_mode = pdata->qe_mode;
398 mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8; 414 mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
399 mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8; 415 mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
400 416
417 mpc83xx_spi->rx_shift = 0;
418 mpc83xx_spi->tx_shift = 0;
419 if (mpc83xx_spi->qe_mode) {
420 mpc83xx_spi->rx_shift = 16;
421 mpc83xx_spi->tx_shift = 24;
422 }
423
401 mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup; 424 mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup;
402 init_completion(&mpc83xx_spi->done); 425 init_completion(&mpc83xx_spi->done);
403 426
@@ -432,6 +455,9 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
432 455
433 /* Enable SPI interface */ 456 /* Enable SPI interface */
434 regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; 457 regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE;
458 if (pdata->qe_mode)
459 regval |= SPMODE_OP;
460
435 mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); 461 mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
436 462
437 ret = spi_bitbang_start(&mpc83xx_spi->bitbang); 463 ret = spi_bitbang_start(&mpc83xx_spi->bitbang);
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 12e631f0fb77..695741b0e420 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -112,7 +112,7 @@ struct fsl_usb2_platform_data {
112struct fsl_spi_platform_data { 112struct fsl_spi_platform_data {
113 u32 initial_spmode; /* initial SPMODE value */ 113 u32 initial_spmode; /* initial SPMODE value */
114 u16 bus_num; 114 u16 bus_num;
115 115 bool qe_mode;
116 /* board specific information */ 116 /* board specific information */
117 u16 max_chipselect; 117 u16 max_chipselect;
118 void (*activate_cs)(u8 cs, u8 polarity); 118 void (*activate_cs)(u8 cs, u8 polarity);