Saturday, September 18, 2010

Linux SPI

My notes while reading about Linux and SPI.

De facto - no standardization like i2c/smbus.
Master/slave like i2c
Faster clock 10MHz vs 400kHz i2c

Full duplex, unlike i2c.
Daisy chaining (in addition to / instead of) wired-AND bus like i2c.
Dedicated chip select signals instead of i2c addressing.

Linux software support only applies to master side, like i2c.

Four clocking modes (?)
- CPOL - clock starts low(0)/high(1)
- CPHA - sample data on leading(0)/trailing(1) edge

- SCK - clock, idle when not used like in i2c
- MOSI: Master Out, Slave In
- MISO: Master In, Slave Out
- nCSx: Chip select(s)
- device specific signals

Generally no interoperability above bit-level
- word lengths vary.
- endianness varies
- no discovery or enumeration mechanism

- MicroWire: half duplex
- Synchronous serial protocl SSP
- Programmable serial protocol PSP
- three wire SPI with single data signal MOMI/SISO

SPI slave chips
- DataFlash <> driver name
- probed based spi_board_info associated to spi_master

spi_board_info - declares a slave chip present on the board
- driver name
- speed
- bus number, to match spi_master bus number
- chip select
- controller data, spi_master driver specific extra data

- spi_register_master()
- typically registered by a platform driver, probed for platform device
- transfer() - asynchronously queue job only - no sleeping
- needs to invoke complete callback - can be a context with no sleeping

- atomic series of spi_transfer segments
- chip select
- typically activated before first transfer, deactivated after last
- can flash inactive between individual xfers
- can leave cs active after the laster xfer in a message

- read and/or write @ bits per word, speed, delay after xfer
- native CPU order words in buffers
- words right justified, unused bits in MSB
- buffer length always specified in bytes

- allocates a message and a number of transfers, buggy?

- low level message transfer

- synchronous, sleeping message with transfers

spi_device.write() &
- single half duplex synchronous transfer

spi.device.w8r8 / w8r16, common synchronous simple read/write transfer sequences

bitbang spi

- implement bitbang.chipselect()
- devices with multi word fifo: implement bitbang.txrx_bufs()
- device with single word shift register: implement bitbang.txrx_word[4]()
- device with GPIO: implement setsck(), setmosi(), getmiso()
- device with a gpio layer implementation
- declare master gpios clk,miso,mosi using spi_gio platform data
- declare chipselect gpios by shoehorning them into spi_board_info controller data.
- no need to implement chipselect()