diff options
author | Joakim Tjernlund <joakim.tjernlund@transmode.se> | 2007-07-17 07:04:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-17 13:23:05 -0400 |
commit | f29ba280ecb46331c1f6842b094808af01131422 (patch) | |
tree | 8339b89c61aed49b186163bfeccd0ab8ccca15c4 /drivers | |
parent | ae918c02d365c884bccb193960db41364868bb7b (diff) |
spi_mpc83xx.c: support QE enabled 83xx CPU's like mpc832x
Quicc Engine enabled mpc83xx CPU's has a somewhat different HW interface to
the SPI controller. This patch adds a qe_mode knob that sees to that
needed adaptions are performed.
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/spi_mpc83xx.c | 32 |
1 files changed, 29 insertions, 3 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) | |||
103 | void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \ | 109 | void 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); |