Skip to content

Commit 9708c12

Browse files
Stephen Streetgregkh
authored andcommitted
[PATCH] spi: Update to PXA2xx SPI Driver
Fix two outstanding issues with the pxa2xx_spi driver: 1) Bad cast in the function u32_writer. Thanks to Henrik Bechmann 2) Adds support for per transfer changes to speed and bits per word Signed-off-by: Stephen Street <[email protected]> Cc: David Brownell <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent a020ed7 commit 9708c12

File tree

1 file changed

+75
-7
lines changed

1 file changed

+75
-7
lines changed

drivers/spi/pxa2xx_spi.c

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ struct driver_data {
120120
dma_addr_t tx_dma;
121121
size_t rx_map_len;
122122
size_t tx_map_len;
123+
u8 n_bytes;
124+
u32 dma_width;
123125
int cs_change;
124126
void (*write)(struct driver_data *drv_data);
125127
void (*read)(struct driver_data *drv_data);
@@ -139,6 +141,8 @@ struct chip_data {
139141
u32 threshold;
140142
u32 dma_threshold;
141143
u8 enable_dma;
144+
u8 bits_per_word;
145+
u32 speed_hz;
142146
void (*write)(struct driver_data *drv_data);
143147
void (*read)(struct driver_data *drv_data);
144148
void (*cs_control)(u32 command);
@@ -186,7 +190,7 @@ static void null_cs_control(u32 command)
186190
static void null_writer(struct driver_data *drv_data)
187191
{
188192
void *reg = drv_data->ioaddr;
189-
u8 n_bytes = drv_data->cur_chip->n_bytes;
193+
u8 n_bytes = drv_data->n_bytes;
190194

191195
while ((read_SSSR(reg) & SSSR_TNF)
192196
&& (drv_data->tx < drv_data->tx_end)) {
@@ -198,7 +202,7 @@ static void null_writer(struct driver_data *drv_data)
198202
static void null_reader(struct driver_data *drv_data)
199203
{
200204
void *reg = drv_data->ioaddr;
201-
u8 n_bytes = drv_data->cur_chip->n_bytes;
205+
u8 n_bytes = drv_data->n_bytes;
202206

203207
while ((read_SSSR(reg) & SSSR_RNE)
204208
&& (drv_data->rx < drv_data->rx_end)) {
@@ -256,7 +260,7 @@ static void u32_writer(struct driver_data *drv_data)
256260

257261
while ((read_SSSR(reg) & SSSR_TNF)
258262
&& (drv_data->tx < drv_data->tx_end)) {
259-
write_SSDR(*(u16 *)(drv_data->tx), reg);
263+
write_SSDR(*(u32 *)(drv_data->tx), reg);
260264
drv_data->tx += 4;
261265
}
262266
}
@@ -677,6 +681,10 @@ static void pump_transfers(unsigned long data)
677681
struct spi_transfer *previous = NULL;
678682
struct chip_data *chip = NULL;
679683
void *reg = drv_data->ioaddr;
684+
u32 clk_div = 0;
685+
u8 bits = 0;
686+
u32 speed = 0;
687+
u32 cr0;
680688

681689
/* Get current state information */
682690
message = drv_data->cur_msg;
@@ -713,6 +721,8 @@ static void pump_transfers(unsigned long data)
713721
giveback(message, drv_data);
714722
return;
715723
}
724+
drv_data->n_bytes = chip->n_bytes;
725+
drv_data->dma_width = chip->dma_width;
716726
drv_data->cs_control = chip->cs_control;
717727
drv_data->tx = (void *)transfer->tx_buf;
718728
drv_data->tx_end = drv_data->tx + transfer->len;
@@ -724,6 +734,62 @@ static void pump_transfers(unsigned long data)
724734
drv_data->write = drv_data->tx ? chip->write : null_writer;
725735
drv_data->read = drv_data->rx ? chip->read : null_reader;
726736
drv_data->cs_change = transfer->cs_change;
737+
738+
/* Change speed and bit per word on a per transfer */
739+
if (transfer->speed_hz || transfer->bits_per_word) {
740+
741+
/* Disable clock */
742+
write_SSCR0(chip->cr0 & ~SSCR0_SSE, reg);
743+
cr0 = chip->cr0;
744+
bits = chip->bits_per_word;
745+
speed = chip->speed_hz;
746+
747+
if (transfer->speed_hz)
748+
speed = transfer->speed_hz;
749+
750+
if (transfer->bits_per_word)
751+
bits = transfer->bits_per_word;
752+
753+
if (reg == SSP1_VIRT)
754+
clk_div = SSP1_SerClkDiv(speed);
755+
else if (reg == SSP2_VIRT)
756+
clk_div = SSP2_SerClkDiv(speed);
757+
else if (reg == SSP3_VIRT)
758+
clk_div = SSP3_SerClkDiv(speed);
759+
760+
if (bits <= 8) {
761+
drv_data->n_bytes = 1;
762+
drv_data->dma_width = DCMD_WIDTH1;
763+
drv_data->read = drv_data->read != null_reader ?
764+
u8_reader : null_reader;
765+
drv_data->write = drv_data->write != null_writer ?
766+
u8_writer : null_writer;
767+
} else if (bits <= 16) {
768+
drv_data->n_bytes = 2;
769+
drv_data->dma_width = DCMD_WIDTH2;
770+
drv_data->read = drv_data->read != null_reader ?
771+
u16_reader : null_reader;
772+
drv_data->write = drv_data->write != null_writer ?
773+
u16_writer : null_writer;
774+
} else if (bits <= 32) {
775+
drv_data->n_bytes = 4;
776+
drv_data->dma_width = DCMD_WIDTH4;
777+
drv_data->read = drv_data->read != null_reader ?
778+
u32_reader : null_reader;
779+
drv_data->write = drv_data->write != null_writer ?
780+
u32_writer : null_writer;
781+
}
782+
783+
cr0 = clk_div
784+
| SSCR0_Motorola
785+
| SSCR0_DataSize(bits & 0x0f)
786+
| SSCR0_SSE
787+
| (bits > 16 ? SSCR0_EDSS : 0);
788+
789+
/* Start it back up */
790+
write_SSCR0(cr0, reg);
791+
}
792+
727793
message->state = RUNNING_STATE;
728794

729795
/* Try to map dma buffer and do a dma transfer if successful */
@@ -739,13 +805,13 @@ static void pump_transfers(unsigned long data)
739805
if (drv_data->rx == drv_data->null_dma_buf)
740806
/* No target address increment */
741807
DCMD(drv_data->rx_channel) = DCMD_FLOWSRC
742-
| chip->dma_width
808+
| drv_data->dma_width
743809
| chip->dma_burst_size
744810
| drv_data->len;
745811
else
746812
DCMD(drv_data->rx_channel) = DCMD_INCTRGADDR
747813
| DCMD_FLOWSRC
748-
| chip->dma_width
814+
| drv_data->dma_width
749815
| chip->dma_burst_size
750816
| drv_data->len;
751817

@@ -756,13 +822,13 @@ static void pump_transfers(unsigned long data)
756822
if (drv_data->tx == drv_data->null_dma_buf)
757823
/* No source address increment */
758824
DCMD(drv_data->tx_channel) = DCMD_FLOWTRG
759-
| chip->dma_width
825+
| drv_data->dma_width
760826
| chip->dma_burst_size
761827
| drv_data->len;
762828
else
763829
DCMD(drv_data->tx_channel) = DCMD_INCSRCADDR
764830
| DCMD_FLOWTRG
765-
| chip->dma_width
831+
| drv_data->dma_width
766832
| chip->dma_burst_size
767833
| drv_data->len;
768834

@@ -943,6 +1009,7 @@ static int setup(struct spi_device *spi)
9431009
clk_div = SSP3_SerClkDiv(spi->max_speed_hz);
9441010
else
9451011
return -ENODEV;
1012+
chip->speed_hz = spi->max_speed_hz;
9461013

9471014
chip->cr0 = clk_div
9481015
| SSCR0_Motorola
@@ -987,6 +1054,7 @@ static int setup(struct spi_device *spi)
9871054
kfree(chip);
9881055
return -ENODEV;
9891056
}
1057+
chip->bits_per_word = spi->bits_per_word;
9901058

9911059
spi_set_ctldata(spi, chip);
9921060

0 commit comments

Comments
 (0)