@@ -146,10 +146,31 @@ static inline void bcm2708_rd_fifo(struct bcm2708_spi *bs, int len)
146
146
static inline void bcm2708_wr_fifo (struct bcm2708_spi * bs , int len )
147
147
{
148
148
u8 byte ;
149
+ u16 val ;
149
150
150
151
if (len > bs -> len )
151
152
len = bs -> len ;
152
153
154
+ if (unlikely (bcm2708_rd (bs , SPI_CS ) & SPI_CS_LEN )) {
155
+ /* LoSSI mode */
156
+ if (unlikely (len % 2 )) {
157
+ printk (KERN_ERR "bcm2708_wr_fifo: length must be even, skipping.\n" );
158
+ bs -> len = 0 ;
159
+ return ;
160
+ }
161
+ while (len ) {
162
+ if (bs -> tx_buf ) {
163
+ val = * (const u16 * )bs -> tx_buf ;
164
+ bs -> tx_buf += 2 ;
165
+ } else
166
+ val = 0 ;
167
+ bcm2708_wr (bs , SPI_FIFO , val );
168
+ bs -> len -= 2 ;
169
+ len -= 2 ;
170
+ }
171
+ return ;
172
+ }
173
+
153
174
while (len -- ) {
154
175
byte = bs -> tx_buf ? * bs -> tx_buf ++ : 0 ;
155
176
bcm2708_wr (bs , SPI_FIFO , byte );
@@ -234,8 +255,12 @@ static int bcm2708_setup_state(struct spi_master *master,
234
255
switch (bpw ) {
235
256
case 8 :
236
257
break ;
258
+ case 9 :
259
+ /* Reading in LoSSI mode is a special case. See 'BCM2835 ARM Peripherals' datasheet */
260
+ cs |= SPI_CS_LEN ;
261
+ break ;
237
262
default :
238
- dev_dbg (dev , "setup: invalid bits_per_word %u (must be 8)\n" ,
263
+ dev_dbg (dev , "setup: invalid bits_per_word %u (must be 8 or 9 )\n" ,
239
264
bpw );
240
265
return - EINVAL ;
241
266
}
@@ -283,7 +308,8 @@ static int bcm2708_process_transfer(struct bcm2708_spi *bs,
283
308
ret = bcm2708_setup_state (spi -> master , & spi -> dev , & state ,
284
309
xfer -> speed_hz ? xfer -> speed_hz : spi -> max_speed_hz ,
285
310
spi -> chip_select , spi -> mode ,
286
- spi -> bits_per_word );
311
+ xfer -> bits_per_word ? xfer -> bits_per_word :
312
+ spi -> bits_per_word );
287
313
if (ret )
288
314
return ret ;
289
315
0 commit comments