5353
5454#define SPI_ENGINE_CMD_REG_CLK_DIV 0x0
5555#define SPI_ENGINE_CMD_REG_CONFIG 0x1
56+ #define SPI_ENGINE_CMD_REG_XFER_BITS 0x2
5657
5758#define SPI_ENGINE_MISC_SYNC 0x0
5859#define SPI_ENGINE_MISC_SLEEP 0x1
@@ -157,7 +158,14 @@ static unsigned int spi_engine_get_clk_div(struct spi_engine *spi_engine,
157158static void spi_engine_gen_xfer (struct spi_engine_program * p , bool dry ,
158159 struct spi_transfer * xfer )
159160{
160- unsigned int len = xfer -> len ;
161+ unsigned int len ;
162+
163+ if (xfer -> bits_per_word <= 8 )
164+ len = xfer -> len ;
165+ else if (xfer -> bits_per_word <= 16 )
166+ len = xfer -> len / 2 ;
167+ else
168+ len = xfer -> len / 4 ;
161169
162170 while (len ) {
163171 unsigned int n = min (len , 256U );
@@ -217,6 +225,7 @@ static int spi_engine_compile_message(struct spi_engine *spi_engine,
217225 struct spi_transfer * xfer ;
218226 int clk_div , new_clk_div ;
219227 bool keep_cs = false;
228+ u8 bits_per_word = 0 ;
220229
221230 clk_div = -1 ;
222231
@@ -236,6 +245,13 @@ static int spi_engine_compile_message(struct spi_engine *spi_engine,
236245 clk_div ));
237246 }
238247
248+ if (bits_per_word != xfer -> bits_per_word ) {
249+ bits_per_word = xfer -> bits_per_word ;
250+ spi_engine_program_add_cmd (p , dry ,
251+ SPI_ENGINE_CMD_WRITE (SPI_ENGINE_CMD_REG_XFER_BITS ,
252+ bits_per_word ));
253+ }
254+
239255 spi_engine_gen_xfer (p , dry , xfer );
240256 spi_engine_gen_sleep (p , dry , spi_engine , clk_div , xfer );
241257
@@ -342,16 +358,34 @@ static bool spi_engine_write_tx_fifo(struct spi_engine *spi_engine,
342358 void __iomem * addr = spi_engine -> base + SPI_ENGINE_REG_SDO_DATA_FIFO ;
343359 struct spi_engine_message_state * st = msg -> state ;
344360 unsigned int n , m , i ;
345- const uint8_t * buf ;
346361
347362 n = readl_relaxed (spi_engine -> base + SPI_ENGINE_REG_SDO_FIFO_ROOM );
348363 while (n && st -> tx_length ) {
349- m = min (n , st -> tx_length );
350- buf = st -> tx_buf ;
351- for (i = 0 ; i < m ; i ++ )
352- writel_relaxed (buf [i ], addr );
353- st -> tx_buf += m ;
354- st -> tx_length -= m ;
364+ if (st -> tx_xfer -> bits_per_word <= 8 ) {
365+ const u8 * buf = st -> tx_buf ;
366+
367+ m = min (n , st -> tx_length );
368+ for (i = 0 ; i < m ; i ++ )
369+ writel_relaxed (buf [i ], addr );
370+ st -> tx_buf += m ;
371+ st -> tx_length -= m ;
372+ } else if (st -> tx_xfer -> bits_per_word <= 16 ) {
373+ const u16 * buf = (const u16 * )st -> tx_buf ;
374+
375+ m = min (n , st -> tx_length / 2 );
376+ for (i = 0 ; i < m ; i ++ )
377+ writel_relaxed (buf [i ], addr );
378+ st -> tx_buf += m * 2 ;
379+ st -> tx_length -= m * 2 ;
380+ } else {
381+ const u32 * buf = (const u32 * )st -> tx_buf ;
382+
383+ m = min (n , st -> tx_length / 4 );
384+ for (i = 0 ; i < m ; i ++ )
385+ writel_relaxed (buf [i ], addr );
386+ st -> tx_buf += m * 4 ;
387+ st -> tx_length -= m * 4 ;
388+ }
355389 n -= m ;
356390 if (st -> tx_length == 0 )
357391 spi_engine_tx_next (msg );
@@ -366,16 +400,34 @@ static bool spi_engine_read_rx_fifo(struct spi_engine *spi_engine,
366400 void __iomem * addr = spi_engine -> base + SPI_ENGINE_REG_SDI_DATA_FIFO ;
367401 struct spi_engine_message_state * st = msg -> state ;
368402 unsigned int n , m , i ;
369- uint8_t * buf ;
370403
371404 n = readl_relaxed (spi_engine -> base + SPI_ENGINE_REG_SDI_FIFO_LEVEL );
372405 while (n && st -> rx_length ) {
373- m = min (n , st -> rx_length );
374- buf = st -> rx_buf ;
375- for (i = 0 ; i < m ; i ++ )
376- buf [i ] = readl_relaxed (addr );
377- st -> rx_buf += m ;
378- st -> rx_length -= m ;
406+ if (st -> rx_xfer -> bits_per_word <= 8 ) {
407+ u8 * buf = st -> rx_buf ;
408+
409+ m = min (n , st -> rx_length );
410+ for (i = 0 ; i < m ; i ++ )
411+ buf [i ] = readl_relaxed (addr );
412+ st -> rx_buf += m ;
413+ st -> rx_length -= m ;
414+ } else if (st -> rx_xfer -> bits_per_word <= 16 ) {
415+ u16 * buf = (u16 * )st -> rx_buf ;
416+
417+ m = min (n , st -> rx_length / 2 );
418+ for (i = 0 ; i < m ; i ++ )
419+ buf [i ] = readl_relaxed (addr );
420+ st -> rx_buf += m * 2 ;
421+ st -> rx_length -= m * 2 ;
422+ } else {
423+ u32 * buf = (u32 * )st -> rx_buf ;
424+
425+ m = min (n , st -> rx_length / 4 );
426+ for (i = 0 ; i < m ; i ++ )
427+ buf [i ] = readl_relaxed (addr );
428+ st -> rx_buf += m * 4 ;
429+ st -> rx_length -= m * 4 ;
430+ }
379431 n -= m ;
380432 if (st -> rx_length == 0 )
381433 spi_engine_rx_next (msg );
@@ -596,7 +648,7 @@ static int spi_engine_probe(struct platform_device *pdev)
596648
597649 host -> dev .of_node = pdev -> dev .of_node ;
598650 host -> mode_bits = SPI_CPOL | SPI_CPHA | SPI_3WIRE ;
599- host -> bits_per_word_mask = SPI_BPW_MASK ( 8 );
651+ host -> bits_per_word_mask = SPI_BPW_RANGE_MASK ( 1 , 32 );
600652 host -> max_speed_hz = clk_get_rate (spi_engine -> ref_clk ) / 2 ;
601653 host -> transfer_one_message = spi_engine_transfer_one_message ;
602654 host -> prepare_message = spi_engine_prepare_message ;
0 commit comments