aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi_mpc83xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi_mpc83xx.c')
-rw-r--r--drivers/spi/spi_mpc83xx.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 3295cfcc9f20..0c16a2b39b41 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -39,6 +39,7 @@ struct mpc83xx_spi_reg {
39}; 39};
40 40
41/* SPI Controller mode register definitions */ 41/* SPI Controller mode register definitions */
42#define SPMODE_LOOP (1 << 30)
42#define SPMODE_CI_INACTIVEHIGH (1 << 29) 43#define SPMODE_CI_INACTIVEHIGH (1 << 29)
43#define SPMODE_CP_BEGIN_EDGECLK (1 << 28) 44#define SPMODE_CP_BEGIN_EDGECLK (1 << 28)
44#define SPMODE_DIV16 (1 << 27) 45#define SPMODE_DIV16 (1 << 27)
@@ -153,12 +154,18 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
153 len = len - 1; 154 len = len - 1;
154 155
155 /* mask out bits we are going to set */ 156 /* mask out bits we are going to set */
156 regval &= ~0x38ff0000; 157 regval &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
158 | SPMODE_LEN(0xF) | SPMODE_DIV16
159 | SPMODE_PM(0xF) | SPMODE_REV | SPMODE_LOOP);
157 160
158 if (spi->mode & SPI_CPHA) 161 if (spi->mode & SPI_CPHA)
159 regval |= SPMODE_CP_BEGIN_EDGECLK; 162 regval |= SPMODE_CP_BEGIN_EDGECLK;
160 if (spi->mode & SPI_CPOL) 163 if (spi->mode & SPI_CPOL)
161 regval |= SPMODE_CI_INACTIVEHIGH; 164 regval |= SPMODE_CI_INACTIVEHIGH;
165 if (!(spi->mode & SPI_LSB_FIRST))
166 regval |= SPMODE_REV;
167 if (spi->mode & SPI_LOOP)
168 regval |= SPMODE_LOOP;
162 169
163 regval |= SPMODE_LEN(len); 170 regval |= SPMODE_LEN(len);
164 171
@@ -176,6 +183,8 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
176 regval |= SPMODE_PM(pm); 183 regval |= SPMODE_PM(pm);
177 } 184 }
178 185
186 /* Turn off SPI unit prior changing mode */
187 mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
179 mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); 188 mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
180 if (mpc83xx_spi->activate_cs) 189 if (mpc83xx_spi->activate_cs)
181 mpc83xx_spi->activate_cs(spi->chip_select, pol); 190 mpc83xx_spi->activate_cs(spi->chip_select, pol);
@@ -231,6 +240,14 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
231 } else 240 } else
232 return -EINVAL; 241 return -EINVAL;
233 242
243 if (mpc83xx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) {
244 mpc83xx_spi->tx_shift = 0;
245 if (bits_per_word <= 8)
246 mpc83xx_spi->rx_shift = 8;
247 else
248 mpc83xx_spi->rx_shift = 0;
249 }
250
234 /* nsecs = (clock period)/2 */ 251 /* nsecs = (clock period)/2 */
235 if (!hz) 252 if (!hz)
236 hz = spi->max_speed_hz; 253 hz = spi->max_speed_hz;
@@ -245,17 +262,22 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
245 262
246 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); 263 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
247 264
248 /* Mask out bits_per_wordgth */ 265 /* mask out bits we are going to set */
249 regval &= 0xff0fffff; 266 regval &= ~(SPMODE_LEN(0xF) | SPMODE_REV);
250 regval |= SPMODE_LEN(bits_per_word); 267 regval |= SPMODE_LEN(bits_per_word);
268 if (!(spi->mode & SPI_LSB_FIRST))
269 regval |= SPMODE_REV;
251 270
271 /* Turn off SPI unit prior changing mode */
272 mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
252 mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval); 273 mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
253 274
254 return 0; 275 return 0;
255} 276}
256 277
257/* the spi->mode bits understood by this driver: */ 278/* the spi->mode bits understood by this driver: */
258#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH) 279#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
280 | SPI_LSB_FIRST | SPI_LOOP)
259 281
260static int mpc83xx_spi_setup(struct spi_device *spi) 282static int mpc83xx_spi_setup(struct spi_device *spi)
261{ 283{