diff options
Diffstat (limited to 'drivers/spi/pxa2xx_spi.c')
-rw-r--r-- | drivers/spi/pxa2xx_spi.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 365e0e355aea..59deed79e0ab 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -51,13 +51,19 @@ MODULE_LICENSE("GPL"); | |||
51 | #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) | 51 | #define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) |
52 | #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) | 52 | #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) |
53 | 53 | ||
54 | /* for testing SSCR1 changes that require SSP restart, basically | 54 | /* |
55 | * everything except the service and interrupt enables */ | 55 | * for testing SSCR1 changes that require SSP restart, basically |
56 | #define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_EBCEI | SSCR1_SCFR \ | 56 | * everything except the service and interrupt enables, the pxa270 developer |
57 | * manual says only SSCR1_SCFR, SSCR1_SPH, SSCR1_SPO need to be in this | ||
58 | * list, but the PXA255 dev man says all bits without really meaning the | ||
59 | * service and interrupt enables | ||
60 | */ | ||
61 | #define SSCR1_CHANGE_MASK (SSCR1_TTELP | SSCR1_TTE | SSCR1_SCFR \ | ||
57 | | SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \ | 62 | | SSCR1_ECRA | SSCR1_ECRB | SSCR1_SCLKDIR \ |
58 | | SSCR1_RWOT | SSCR1_TRAIL | SSCR1_PINTE \ | 63 | | SSCR1_SFRMDIR | SSCR1_RWOT | SSCR1_TRAIL \ |
59 | | SSCR1_STRF | SSCR1_EFWR |SSCR1_RFT \ | 64 | | SSCR1_IFS | SSCR1_STRF | SSCR1_EFWR \ |
60 | | SSCR1_TFT | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) | 65 | | SSCR1_RFT | SSCR1_TFT | SSCR1_MWDS \ |
66 | | SSCR1_SPH | SSCR1_SPO | SSCR1_LBM) | ||
61 | 67 | ||
62 | #define DEFINE_SSP_REG(reg, off) \ | 68 | #define DEFINE_SSP_REG(reg, off) \ |
63 | static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \ | 69 | static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \ |
@@ -973,9 +979,6 @@ static void pump_transfers(unsigned long data) | |||
973 | if (drv_data->ssp_type == PXA25x_SSP) | 979 | if (drv_data->ssp_type == PXA25x_SSP) |
974 | DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN; | 980 | DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN; |
975 | 981 | ||
976 | /* Fix me, need to handle cs polarity */ | ||
977 | drv_data->cs_control(PXA2XX_CS_ASSERT); | ||
978 | |||
979 | /* Clear status and start DMA engine */ | 982 | /* Clear status and start DMA engine */ |
980 | cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1; | 983 | cr1 = chip->cr1 | dma_thresh | drv_data->dma_cr1; |
981 | write_SSSR(drv_data->clear_sr, reg); | 984 | write_SSSR(drv_data->clear_sr, reg); |
@@ -985,9 +988,6 @@ static void pump_transfers(unsigned long data) | |||
985 | /* Ensure we have the correct interrupt handler */ | 988 | /* Ensure we have the correct interrupt handler */ |
986 | drv_data->transfer_handler = interrupt_transfer; | 989 | drv_data->transfer_handler = interrupt_transfer; |
987 | 990 | ||
988 | /* Fix me, need to handle cs polarity */ | ||
989 | drv_data->cs_control(PXA2XX_CS_ASSERT); | ||
990 | |||
991 | /* Clear status */ | 991 | /* Clear status */ |
992 | cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1; | 992 | cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1; |
993 | write_SSSR(drv_data->clear_sr, reg); | 993 | write_SSSR(drv_data->clear_sr, reg); |
@@ -998,16 +998,29 @@ static void pump_transfers(unsigned long data) | |||
998 | || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) != | 998 | || (read_SSCR1(reg) & SSCR1_CHANGE_MASK) != |
999 | (cr1 & SSCR1_CHANGE_MASK)) { | 999 | (cr1 & SSCR1_CHANGE_MASK)) { |
1000 | 1000 | ||
1001 | /* stop the SSP, and update the other bits */ | ||
1001 | write_SSCR0(cr0 & ~SSCR0_SSE, reg); | 1002 | write_SSCR0(cr0 & ~SSCR0_SSE, reg); |
1002 | if (drv_data->ssp_type != PXA25x_SSP) | 1003 | if (drv_data->ssp_type != PXA25x_SSP) |
1003 | write_SSTO(chip->timeout, reg); | 1004 | write_SSTO(chip->timeout, reg); |
1004 | write_SSCR1(cr1, reg); | 1005 | /* first set CR1 without interrupt and service enables */ |
1006 | write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg); | ||
1007 | /* restart the SSP */ | ||
1005 | write_SSCR0(cr0, reg); | 1008 | write_SSCR0(cr0, reg); |
1009 | |||
1006 | } else { | 1010 | } else { |
1007 | if (drv_data->ssp_type != PXA25x_SSP) | 1011 | if (drv_data->ssp_type != PXA25x_SSP) |
1008 | write_SSTO(chip->timeout, reg); | 1012 | write_SSTO(chip->timeout, reg); |
1009 | write_SSCR1(cr1, reg); | ||
1010 | } | 1013 | } |
1014 | |||
1015 | /* FIXME, need to handle cs polarity, | ||
1016 | * this driver uses struct pxa2xx_spi_chip.cs_control to | ||
1017 | * specify a CS handling function, and it ignores most | ||
1018 | * struct spi_device.mode[s], including SPI_CS_HIGH */ | ||
1019 | drv_data->cs_control(PXA2XX_CS_ASSERT); | ||
1020 | |||
1021 | /* after chip select, release the data by enabling service | ||
1022 | * requests and interrupts, without changing any mode bits */ | ||
1023 | write_SSCR1(cr1, reg); | ||
1011 | } | 1024 | } |
1012 | 1025 | ||
1013 | static void pump_messages(struct work_struct *work) | 1026 | static void pump_messages(struct work_struct *work) |