aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-orion.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-orion.c')
-rw-r--r--drivers/spi/spi-orion.c88
1 files changed, 37 insertions, 51 deletions
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index 3dec9e0b99b8..861664776672 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -28,7 +28,12 @@
28/* Runtime PM autosuspend timeout: PM is fairly light on this driver */ 28/* Runtime PM autosuspend timeout: PM is fairly light on this driver */
29#define SPI_AUTOSUSPEND_TIMEOUT 200 29#define SPI_AUTOSUSPEND_TIMEOUT 200
30 30
31#define ORION_NUM_CHIPSELECTS 1 /* only one slave is supported*/ 31/* Some SoCs using this driver support up to 8 chip selects.
32 * It is up to the implementer to only use the chip selects
33 * that are available.
34 */
35#define ORION_NUM_CHIPSELECTS 8
36
32#define ORION_SPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */ 37#define ORION_SPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */
33 38
34#define ORION_SPI_IF_CTRL_REG 0x00 39#define ORION_SPI_IF_CTRL_REG 0x00
@@ -44,6 +49,10 @@
44#define ARMADA_SPI_CLK_PRESCALE_MASK 0xDF 49#define ARMADA_SPI_CLK_PRESCALE_MASK 0xDF
45#define ORION_SPI_MODE_MASK (ORION_SPI_MODE_CPOL | \ 50#define ORION_SPI_MODE_MASK (ORION_SPI_MODE_CPOL | \
46 ORION_SPI_MODE_CPHA) 51 ORION_SPI_MODE_CPHA)
52#define ORION_SPI_CS_MASK 0x1C
53#define ORION_SPI_CS_SHIFT 2
54#define ORION_SPI_CS(cs) ((cs << ORION_SPI_CS_SHIFT) & \
55 ORION_SPI_CS_MASK)
47 56
48enum orion_spi_type { 57enum orion_spi_type {
49 ORION_SPI, 58 ORION_SPI,
@@ -215,9 +224,18 @@ orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
215 return 0; 224 return 0;
216} 225}
217 226
218static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable) 227static void orion_spi_set_cs(struct spi_device *spi, bool enable)
219{ 228{
220 if (enable) 229 struct orion_spi *orion_spi;
230
231 orion_spi = spi_master_get_devdata(spi->master);
232
233 orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, ORION_SPI_CS_MASK);
234 orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG,
235 ORION_SPI_CS(spi->chip_select));
236
237 /* Chip select logic is inverted from spi_set_cs */
238 if (!enable)
221 orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); 239 orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
222 else 240 else
223 orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); 241 orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
@@ -332,64 +350,31 @@ out:
332 return xfer->len - count; 350 return xfer->len - count;
333} 351}
334 352
335static int orion_spi_transfer_one_message(struct spi_master *master, 353static int orion_spi_transfer_one(struct spi_master *master,
336 struct spi_message *m) 354 struct spi_device *spi,
355 struct spi_transfer *t)
337{ 356{
338 struct orion_spi *orion_spi = spi_master_get_devdata(master);
339 struct spi_device *spi = m->spi;
340 struct spi_transfer *t = NULL;
341 int par_override = 0;
342 int status = 0; 357 int status = 0;
343 int cs_active = 0;
344
345 /* Load defaults */
346 status = orion_spi_setup_transfer(spi, NULL);
347 358
359 status = orion_spi_setup_transfer(spi, t);
348 if (status < 0) 360 if (status < 0)
349 goto msg_done; 361 return status;
350
351 list_for_each_entry(t, &m->transfers, transfer_list) {
352 if (par_override || t->speed_hz || t->bits_per_word) {
353 par_override = 1;
354 status = orion_spi_setup_transfer(spi, t);
355 if (status < 0)
356 break;
357 if (!t->speed_hz && !t->bits_per_word)
358 par_override = 0;
359 }
360
361 if (!cs_active) {
362 orion_spi_set_cs(orion_spi, 1);
363 cs_active = 1;
364 }
365 362
366 if (t->len) 363 if (t->len)
367 m->actual_length += orion_spi_write_read(spi, t); 364 orion_spi_write_read(spi, t);
368 365
369 if (t->delay_usecs) 366 return status;
370 udelay(t->delay_usecs); 367}
371
372 if (t->cs_change) {
373 orion_spi_set_cs(orion_spi, 0);
374 cs_active = 0;
375 }
376 }
377
378msg_done:
379 if (cs_active)
380 orion_spi_set_cs(orion_spi, 0);
381
382 m->status = status;
383 spi_finalize_current_message(master);
384 368
385 return 0; 369static int orion_spi_setup(struct spi_device *spi)
370{
371 return orion_spi_setup_transfer(spi, NULL);
386} 372}
387 373
388static int orion_spi_reset(struct orion_spi *orion_spi) 374static int orion_spi_reset(struct orion_spi *orion_spi)
389{ 375{
390 /* Verify that the CS is deasserted */ 376 /* Verify that the CS is deasserted */
391 orion_spi_set_cs(orion_spi, 0); 377 orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
392
393 return 0; 378 return 0;
394} 379}
395 380
@@ -442,9 +427,10 @@ static int orion_spi_probe(struct platform_device *pdev)
442 427
443 /* we support only mode 0, and no options */ 428 /* we support only mode 0, and no options */
444 master->mode_bits = SPI_CPHA | SPI_CPOL; 429 master->mode_bits = SPI_CPHA | SPI_CPOL;
445 430 master->set_cs = orion_spi_set_cs;
446 master->transfer_one_message = orion_spi_transfer_one_message; 431 master->transfer_one = orion_spi_transfer_one;
447 master->num_chipselect = ORION_NUM_CHIPSELECTS; 432 master->num_chipselect = ORION_NUM_CHIPSELECTS;
433 master->setup = orion_spi_setup;
448 master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); 434 master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
449 master->auto_runtime_pm = true; 435 master->auto_runtime_pm = true;
450 436