Serial Peripheral Interface (SPI)¶
SPI is the “Serial Peripheral Interface”, widely used with embeddedsystems because it is a simple and efficient interface: basically amultiplexed shift register. Its three signal wires hold a clock (SCK,often in the range of 1-20 MHz), a “Master Out, Slave In” (MOSI) dataline, and a “Master In, Slave Out” (MISO) data line. SPI is a fullduplex protocol; for each bit shifted out the MOSI line (one per clock)another is shifted in on the MISO line. Those bits are assembled intowords of various sizes on the way to and from system memory. Anadditional chipselect line is usually active-low (nCS); four signals arenormally used for each peripheral, plus sometimes an interrupt.
The SPI bus facilities listed here provide a generalized interface todeclare SPI buses and devices, manage them according to the standardLinux driver model, and perform input/output operations. At this time,only “master” side interfaces are supported, where Linux talks to SPIperipherals and does not implement such a peripheral itself. (Interfacesto support implementing SPI slaves would necessarily look different.)
The programming interface is structured around two kinds of driver, andtwo kinds of device. A “Controller Driver” abstracts the controllerhardware, which may be as simple as a set of GPIO pins or as complex asa pair of FIFOs connected to dual DMA engines on the other side of theSPI shift register (maximizing throughput). Such drivers bridge betweenwhatever bus they sit on (often the platform bus) and SPI, and exposethe SPI side of their device as astructspi_controller. SPI devices are children of that master,represented as astructspi_device andmanufactured fromstructspi_board_info descriptors which are usually provided byboard-specific initialization code. Astructspi_driver is called a “Protocol Driver”, and is bound to aspi_device using normal driver model calls.
The I/O model is a set of queued messages. Protocol drivers submit oneor morestructspi_message objects,which are processed and completed asynchronously. (There are synchronouswrappers, however.) Messages are built from one or morestructspi_transfer objects, each ofwhich wraps a full duplex SPI transfer. A variety of protocol tweakingoptions are needed, because different chips adopt very differentpolicies for how they use the bits transferred with SPI.
- structspi_statistics¶
statistics for spi transfers
Definition:
struct spi_statistics { struct u64_stats_sync syncp; u64_stats_t messages; u64_stats_t transfers; u64_stats_t errors; u64_stats_t timedout; u64_stats_t spi_sync; u64_stats_t spi_sync_immediate; u64_stats_t spi_async; u64_stats_t bytes; u64_stats_t bytes_rx; u64_stats_t bytes_tx;#define SPI_STATISTICS_HISTO_SIZE 17; u64_stats_t transfer_bytes_histo[SPI_STATISTICS_HISTO_SIZE]; u64_stats_t transfers_split_maxsize;};Members
syncpseqcount to protect members in this struct for per-cpu updateon 32-bit systems
messagesnumber of spi-messages handled
transfersnumber of spi_transfers handled
errorsnumber of errors during spi_transfer
timedoutnumber of timeouts during spi_transfer
spi_syncnumber of times spi_sync is used
spi_sync_immediatenumber of times spi_sync is executed immediatelyin calling context without queuing and scheduling
spi_asyncnumber of times spi_async is used
bytesnumber of bytes transferred to/from device
bytes_rxnumber of bytes received from device
bytes_txnumber of bytes sent to device
transfer_bytes_histotransfer bytes histogram
transfers_split_maxsizenumber of transfers that have been split because ofmaxsize limit
- structspi_delay¶
SPI delay information
Definition:
struct spi_delay {#define SPI_DELAY_UNIT_USECS 0;#define SPI_DELAY_UNIT_NSECS 1;#define SPI_DELAY_UNIT_SCK 2; u16 value; u8 unit;};Members
valueValue for the delay
unitUnit for the delay
- structspi_device¶
Controller side proxy for an SPI target device
Definition:
struct spi_device { struct device dev; struct spi_controller *controller; u32 max_speed_hz; u8 bits_per_word; bool rt;#define SPI_NO_TX BIT(31);#define SPI_NO_RX BIT(30);#define SPI_TPM_HW_FLOW BIT(29);#define SPI_MODE_KERNEL_MASK (~(BIT(29) - 1)); u32 mode; int irq; void *controller_state; void *controller_data; char modalias[SPI_NAME_SIZE]; const char *driver_override; struct spi_statistics __percpu *pcpu_statistics; struct spi_delay word_delay; struct spi_delay cs_setup; struct spi_delay cs_hold; struct spi_delay cs_inactive; u8 chip_select[SPI_DEVICE_CS_CNT_MAX]; u8 num_chipselect; u32 cs_index_mask : SPI_DEVICE_CS_CNT_MAX; struct gpio_desc *cs_gpiod[SPI_DEVICE_CS_CNT_MAX];};Members
devDriver model representation of the device.
controllerSPI controller used with the device.
max_speed_hzMaximum clock rate to be used with this chip(on this board); may be changed by the device’s driver.The spi_transfer.speed_hz can override this for each transfer.
bits_per_wordData transfers involve one or more words; word sizeslike eight or 12 bits are common. In-memory wordsizes arepowers of two bytes (e.g. 20 bit samples use 32 bits).This may be changed by the device’s driver, or left at thedefault (0) indicating protocol words are eight bit bytes.The spi_transfer.bits_per_word can override this for each transfer.
rtMake the pump thread real time priority.
modeThe spi mode defines how data is clocked out and in.This may be changed by the device’s driver.The “active low” default for chipselect mode can be overridden(by specifying SPI_CS_HIGH) as can the “MSB first” default foreach word in a transfer (by specifying SPI_LSB_FIRST).
irqNegative, or the number passed to
request_irq()to receiveinterrupts from this device.controller_stateController’s runtime state
controller_dataBoard-specific definitions for controller, such asFIFO initialization parameters; from board_info.controller_data
modaliasName of the driver to use with this device, or an aliasfor that name. This appears in the sysfs “modalias” attributefor driver coldplugging, and in uevents used for hotplugging
driver_overrideIf the name of a driver is written to this attribute, thenthe device will bind to the named driver and only the named driver.Do not set directly, because core frees it; use
driver_set_override()toset or clear it.pcpu_statisticsstatistics for the spi_device
word_delaydelay to be inserted between consecutivewords of a transfer
cs_setupdelay to be introduced by the controller after CS is asserted
cs_holddelay to be introduced by the controller before CS is deasserted
cs_inactivedelay to be introduced by the controller after CS isdeasserted. Ifcs_change_delay is used fromspi_transfer, then thetwo delays will be added up.
chip_selectArray of physical chipselect, spi->chipselect[i] givesthe corresponding physical CS for logical CS i.
num_chipselectNumber of physical chipselects used.
cs_index_maskBit mask of the active chipselect(s) in the chipselect array
cs_gpiodArray of GPIO descriptors of the corresponding chipselect lines(optional, NULL when not using a GPIO line)
Description
Aspi_device is used to interchange data between an SPI target device(usually a discrete chip) and CPU memory.
Indev, the platform_data is used to hold information about thisdevice that’s meaningful to the device’s protocol driver, but notto its controller. One example might be an identifier for a chipvariant with slightly different functionality; another might beinformation about how this particular board wires the chip’s pins.
- structspi_driver¶
Host side “protocol” driver
Definition:
struct spi_driver { const struct spi_device_id *id_table; int (*probe)(struct spi_device *spi); void (*remove)(struct spi_device *spi); void (*shutdown)(struct spi_device *spi); struct device_driver driver;};Members
id_tableList of SPI devices supported by this driver
probeBinds this driver to the SPI device. Drivers can verifythat the device is actually present, and may need to configurecharacteristics (such as bits_per_word) which weren’t needed forthe initial configuration done during system setup.
removeUnbinds this driver from the SPI device
shutdownStandard shutdown callback used during system statetransitions such as powerdown/halt and kexec
driverSPI device drivers should initialize the name and ownerfield of this structure.
Description
This represents the kind of device driver that uses SPI messages tointeract with the hardware at the other end of a SPI link. It’s calleda “protocol” driver because it works through messages rather than talkingdirectly to SPI hardware (which is what the underlying SPI controllerdriver does to pass those messages). These protocols are defined in thespecification for the device(s) supported by the driver.
As a rule, those device protocols represent the lowest level interfacesupported by a driver, and it will support upper level interfaces too.Examples of such upper levels include frameworks like MTD, networking,MMC, RTC, filesystem character device nodes, and hardware monitoring.
- voidspi_unregister_driver(structspi_driver*sdrv)¶
reverse effect of spi_register_driver
Parameters
structspi_driver*sdrvthe driver to unregister
Context
can sleep
- module_spi_driver¶
module_spi_driver(__spi_driver)
Helper macro for registering a SPI driver
Parameters
__spi_driverspi_driver struct
Description
Helper macro for SPI drivers which do not do anything special in moduleinit/exit. This eliminates a lot of boilerplate. Each module may onlyuse this macro once, and calling it replacesmodule_init() andmodule_exit()
- structspi_controller¶
interface to SPI host or target controller
Definition:
struct spi_controller { struct device dev; struct list_head list; s16 bus_num; u16 num_chipselect; u16 dma_alignment; u32 mode_bits; u32 buswidth_override_bits; u32 bits_per_word_mask;#define SPI_BPW_MASK(bits) BIT((bits) - 1);#define SPI_BPW_RANGE_MASK(min, max) GENMASK((max) - 1, (min) - 1); u32 min_speed_hz; u32 max_speed_hz; u16 flags;#define SPI_CONTROLLER_HALF_DUPLEX BIT(0);#define SPI_CONTROLLER_NO_RX BIT(1);#define SPI_CONTROLLER_NO_TX BIT(2);#define SPI_CONTROLLER_MUST_RX BIT(3);#define SPI_CONTROLLER_MUST_TX BIT(4);#define SPI_CONTROLLER_GPIO_SS BIT(5);#define SPI_CONTROLLER_SUSPENDED BIT(6);#define SPI_CONTROLLER_MULTI_CS BIT(7); bool devm_allocated; union { bool slave; bool target; }; size_t (*max_transfer_size)(struct spi_device *spi); size_t (*max_message_size)(struct spi_device *spi); struct mutex io_mutex; struct mutex add_lock; spinlock_t bus_lock_spinlock; struct mutex bus_lock_mutex; bool bus_lock_flag; int (*setup)(struct spi_device *spi); int (*set_cs_timing)(struct spi_device *spi); int (*transfer)(struct spi_device *spi, struct spi_message *mesg); void (*cleanup)(struct spi_device *spi); bool (*can_dma)(struct spi_controller *ctlr, struct spi_device *spi, struct spi_transfer *xfer); struct device *dma_map_dev; struct device *cur_rx_dma_dev; struct device *cur_tx_dma_dev; bool queued; struct kthread_worker *kworker; struct kthread_work pump_messages; spinlock_t queue_lock; struct list_head queue; struct spi_message *cur_msg; struct completion cur_msg_completion; bool cur_msg_incomplete; bool cur_msg_need_completion; bool busy; bool running; bool rt; bool auto_runtime_pm; bool fallback; bool last_cs_mode_high; s8 last_cs[SPI_DEVICE_CS_CNT_MAX]; u32 last_cs_index_mask : SPI_DEVICE_CS_CNT_MAX; struct completion xfer_completion; size_t max_dma_len; int (*optimize_message)(struct spi_message *msg); int (*unoptimize_message)(struct spi_message *msg); int (*prepare_transfer_hardware)(struct spi_controller *ctlr); int (*transfer_one_message)(struct spi_controller *ctlr, struct spi_message *mesg); int (*unprepare_transfer_hardware)(struct spi_controller *ctlr); int (*prepare_message)(struct spi_controller *ctlr, struct spi_message *message); int (*unprepare_message)(struct spi_controller *ctlr, struct spi_message *message); int (*target_abort)(struct spi_controller *ctlr); void (*set_cs)(struct spi_device *spi, bool enable); int (*transfer_one)(struct spi_controller *ctlr, struct spi_device *spi, struct spi_transfer *transfer); void (*handle_err)(struct spi_controller *ctlr, struct spi_message *message); const struct spi_controller_mem_ops *mem_ops; const struct spi_controller_mem_caps *mem_caps; bool dtr_caps; struct spi_offload *(*get_offload)(struct spi_device *spi, const struct spi_offload_config *config); void (*put_offload)(struct spi_offload *offload); struct gpio_desc **cs_gpiods; bool use_gpio_descriptors; s8 unused_native_cs; s8 max_native_cs; struct spi_statistics __percpu *pcpu_statistics; struct dma_chan *dma_tx; struct dma_chan *dma_rx; void *dummy_rx; void *dummy_tx; int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs); bool ptp_sts_supported; unsigned long irq_flags; bool queue_empty; bool must_async; bool defer_optimize_message;};Members
devdevice interface to this driver
listlink with the global spi_controller list
bus_numboard-specific (and often SOC-specific) identifier for agiven SPI controller.
num_chipselectchipselects are used to distinguish individualSPI targets, and are numbered from zero to num_chipselects.each target has a chipselect signal, but it’s common that notevery chipselect is connected to a target.
dma_alignmentSPI controller constraint on DMA buffers alignment.
mode_bitsflags understood by this controller driver
buswidth_override_bitsflags to override for this controller driver
bits_per_word_maskA mask indicating which values of bits_per_word aresupported by the driver. Bit n indicates that a bits_per_word n+1 issupported. If set, the SPI core will reject any transfer with anunsupported bits_per_word. If not set, this value is simply ignored,and it’s up to the individual driver to perform any validation.
min_speed_hzLowest supported transfer speed
max_speed_hzHighest supported transfer speed
flagsother constraints relevant to this driver
devm_allocatedwhether the allocation of this
structisdevres-managed{unnamed_union}anonymous
slaveindicates that this is an SPI slave controller
targetindicates that this is an SPI target controller
max_transfer_sizefunction that returns the max transfer size fora
spi_device; may beNULL, so the defaultSIZE_MAXwill be used.max_message_sizefunction that returns the max message size fora
spi_device; may beNULL, so the defaultSIZE_MAXwill be used.io_mutexmutex for physical bus access
add_lockmutex to avoid adding devices to the same chipselect
bus_lock_spinlockspinlock for SPI bus locking
bus_lock_mutexmutex for exclusion of multiple callers
bus_lock_flagindicates that the SPI bus is locked for exclusive use
setupupdates the device mode and clocking records used by adevice’s SPI controller; protocol code may call this. Thismust fail if an unrecognized or unsupported mode is requested.It’s always safe to call this unless transfers are pending onthe device whose settings are being modified.
set_cs_timingoptional hook for SPI devices to request SPIcontroller for configuring specific CS setup time, hold time and inactivedelay in terms of clock counts
transferadds a message to the controller’s transfer queue.
cleanupfrees controller-specific state
can_dmadetermine whether this controller supports DMA
dma_map_devdevice which can be used for DMA mapping
cur_rx_dma_devdevice which is currently used for RX DMA mapping
cur_tx_dma_devdevice which is currently used for TX DMA mapping
queuedwhether this controller is providing an internal message queue
kworkerpointer to thread struct for message pump
pump_messageswork struct for scheduling work to the message pump
queue_lockspinlock to synchronise access to message queue
queuemessage queue
cur_msgthe currently in-flight message
cur_msg_completiona completion for the current in-flight message
cur_msg_incompleteFlag used internally to opportunistically skipthecur_msg_completion. This flag is used to check if the driver hasalready called
spi_finalize_current_message().cur_msg_need_completionFlag used internally to opportunistically skipthecur_msg_completion. This flag is used to signal the context thatis running
spi_finalize_current_message()that it needs tocomplete()busymessage pump is busy
runningmessage pump is running
rtwhether this queue is set to run as a realtime task
auto_runtime_pmthe core should ensure a runtime PM reference is heldwhile the hardware is prepared, using the parentdevice for the spidev
fallbackfallback to PIO if DMA transfer return failure withSPI_TRANS_FAIL_NO_START.
last_cs_mode_highwas (mode & SPI_CS_HIGH) true on the last call to set_cs.
last_csthe last chip_select that is recorded by set_cs, -1 on non chipselected
last_cs_index_maskbit mask the last chip selects that were used
xfer_completionused by core
transfer_one_message()max_dma_lenMaximum length of a DMA transfer for the device.
optimize_messageoptimize the message for reuse
unoptimize_messagerelease resources allocated by optimize_message
prepare_transfer_hardwarea message will soon arrive from the queueso the subsystem requests the driver to prepare the transfer hardwareby issuing this call
transfer_one_messagethe subsystem calls the driver to transfer a singlemessage while queuing transfers that arrive in the meantime. When thedriver is finished with this message, it must call
spi_finalize_current_message()so the subsystem can issue the nextmessageunprepare_transfer_hardwarethere are currently no more messages on thequeue so the subsystem notifies the driver that it may relax thehardware by issuing this call
prepare_messageset up the controller to transfer a single message,for example doing DMA mapping. Called from threadedcontext.
unprepare_messageundo any work done by
prepare_message().target_abortabort the ongoing transfer request on an SPI target controller
set_csset the logic level of the chip select line. May be calledfrom interrupt context.
transfer_onetransfer a single spi_transfer.
handle_errthe subsystem calls the driver to handle an error that occursin the generic implementation of
transfer_one_message().mem_opsoptimized/dedicated operations for interactions with SPI memory.This field is optional and should only be implemented if thecontroller has native support for memory like operations.
mem_capscontroller capabilities for the handling of memory operations.
dtr_capstrue if controller has dtr(single/dual transfer rate) capability.QSPI based controller should fill this based on controller’s capability.
get_offloadcallback for controllers with offload support to get matchingoffload instance. Implementations should return -ENODEV if no match isfound.
put_offloadrelease the offload instance acquired byget_offload.
cs_gpiodsArray of GPIO descriptors to use as chip select lines; one per CSnumber. Any individual value may be NULL for CS lines thatare not GPIOs (driven by the SPI controller itself).
use_gpio_descriptorsTurns on the code in the SPI core to parse and grabGPIO descriptors. This will fill incs_gpiods and SPI devices will havethe cs_gpiod assigned if a GPIO line is found for the chipselect.
unused_native_csWhen cs_gpiods is used,
spi_register_controller()willfill in this field with the first unused native CS, to be used by SPIcontroller drivers that need to drive a native CS when using GPIO CS.max_native_csWhen cs_gpiods is used, and this field is filled in,
spi_register_controller()will validate all native CS (including theunused native CS) against this value.pcpu_statisticsstatistics for the spi_controller
dma_txDMA transmit channel
dma_rxDMA receive channel
dummy_rxdummy receive buffer for full-duplex devices
dummy_txdummy transmit buffer for full-duplex devices
fw_translate_csIf the boot firmware uses different numbering schemewhat Linux expects, this optional hook can be used to translatebetween the two.
ptp_sts_supportedIf the driver sets this to true, it must provide atime snapshot inspi_transfer->ptp_sts as close as possible to themoment in time whenspi_transfer->ptp_sts_word_pre andspi_transfer->ptp_sts_word_post were transmitted.If the driver does not set this, the SPI core takes the snapshot asclose to the driver hand-over as possible.
irq_flagsInterrupt enable state during PTP system timestamping
queue_emptysignal green light for opportunistically skipping the queuefor spi_sync transfers.
must_asyncdisable all fast paths in the core
defer_optimize_messageset to true if controller cannot pre-optimize messagesand needs to defer the optimization step until the message is actuallybeing transferred
Description
return 0 if the transfer is finished,
return 1 if the transfer is still in progress. Whenthe driver is finished with this transfer it mustcall
spi_finalize_current_transfer()so the subsystemcan issue the next transfer. If the transfer fails, thedriver must set the flag SPI_TRANS_FAIL_IO tospi_transfer->error first, before callingspi_finalize_current_transfer().
Each SPI controller can communicate with one or morespi_devicechildren. These make a small bus, sharing MOSI, MISO and SCK signalsbut not chip select signals. Each device may be configured to use adifferent clock rate, since those shared signals are ignored unlessthe chip is selected.
The driver for an SPI controller manages access to those devices througha queue of spi_message transactions, copying data between CPU memory andan SPI target device. For each such message it queues, it calls themessage’s completion function when the transaction completes.
Note
- transfer_one and transfer_one_message are mutually
exclusive; when both are set, the generic subsystem doesnot call your transfer_one callback.
- structspi_res¶
SPI resource management structure
Definition:
struct spi_res { struct list_head entry; spi_res_release_t release; unsigned long long data[];};Members
entrylist entry
releaserelease code called prior to freeing this resource
dataextra data allocated for the specific use-case
Description
This is based on ideas from devres, but focused on life-cyclemanagement during spi_message processing.
- structspi_transfer¶
a read/write buffer pair
Definition:
struct spi_transfer { const void *tx_buf; void *rx_buf; unsigned len;#define SPI_TRANS_FAIL_NO_START BIT(0);#define SPI_TRANS_FAIL_IO BIT(1); u16 error; bool tx_sg_mapped; bool rx_sg_mapped; struct sg_table tx_sg; struct sg_table rx_sg; dma_addr_t tx_dma; dma_addr_t rx_dma; unsigned dummy_data:1; unsigned cs_off:1; unsigned cs_change:1; unsigned tx_nbits:4; unsigned rx_nbits:4; unsigned timestamped:1; bool dtr_mode;#define SPI_NBITS_SINGLE 0x01;#define SPI_NBITS_DUAL 0x02;#define SPI_NBITS_QUAD 0x04;#define SPI_NBITS_OCTAL 0x08; u8 bits_per_word; struct spi_delay delay; struct spi_delay cs_change_delay; struct spi_delay word_delay; u32 speed_hz; u32 effective_speed_hz; unsigned int offload_flags; unsigned int ptp_sts_word_pre; unsigned int ptp_sts_word_post; struct ptp_system_timestamp *ptp_sts; struct list_head transfer_list;};Members
tx_bufdata to be written (DMA-safe memory), or NULL
rx_bufdata to be read (DMA-safe memory), or NULL
lensize of rx and tx buffers (in bytes)
errorError status logged by SPI controller driver.
tx_sg_mappedIf true, thetx_sg is mapped for DMA
rx_sg_mappedIf true, therx_sg is mapped for DMA
tx_sgScatterlist for transmit, currently not for client use
rx_sgScatterlist for receive, currently not for client use
tx_dmaDMA address of tx_buf, currently not for client use
rx_dmaDMA address of rx_buf, currently not for client use
dummy_dataindicates transfer is dummy bytes transfer.
cs_offperforms the transfer with chipselect off.
cs_changeaffects chipselect after this transfer completes
tx_nbitsnumber of bits used for writing. If 0 the default(SPI_NBITS_SINGLE) is used.
rx_nbitsnumber of bits used for reading. If 0 the default(SPI_NBITS_SINGLE) is used.
timestampedtrue if the transfer has been timestamped
dtr_modetrue if supports double transfer rate.
bits_per_wordselect a bits_per_word other than the device defaultfor this transfer. If 0 the default (fromspi_device) is used.
delaydelay to be introduced after this transfer before(optionally) changing the chipselect status, then startingthe next transfer or completing thisspi_message.
cs_change_delaydelay between cs deassert and assert whencs_change is set andspi_transfer is not the last inspi_message
word_delayinter word delay to be introduced after each word size(set by bits_per_word) transmission.
speed_hzSelect a speed other than the device default for thistransfer. If 0 the default (fromspi_device) is used.
effective_speed_hzthe effective SCK-speed that was used totransfer this transfer. Set to 0 if the SPI bus driver doesnot support it.
offload_flagsFlags that are only applicable to specialized SPI offloadtransfers. See
SPI_OFFLOAD_XFER_*in spi-offload.h.ptp_sts_word_preThe word (subject to bits_per_word semantics) offsetwithintx_buf for which the SPI device is requesting that the timesnapshot for this transfer begins. Upon completing the SPI transfer,this value may have changed compared to what was requested, dependingon the available snapshotting resolution (DMA transfer,ptp_sts_supported is false, etc).
ptp_sts_word_postSeeptp_sts_word_post. The two can be equal (meaningthat a single byte should be snapshotted).If the core takes care of the timestamp (ifptp_sts_supported is falsefor this controller), it will setptp_sts_word_pre to 0, andptp_sts_word_post to the length of the transfer. This is donepurposefully (instead of setting to spi_transfer->len - 1) to denotethat a transfer-level snapshot taken from within the driver may stillbe of higher quality.
ptp_stsPointer to a memory location held by the SPI target device where aPTP system timestamp structure may lie. If drivers use PIO or theirhardware has some sort of assist for retrieving exact transfer timing,they can (and should) assertptp_sts_supported and populate thisstructure using the ptp_read_system_*ts helper functions.The timestamp must represent the time at which the SPI target device hasprocessed the word, i.e. the “pre” timestamp should be taken beforetransmitting the “pre” word, and the “post” timestamp after receivingtransmit confirmation from the controller for the “post” word.
transfer_listtransfers are sequenced throughspi_message.transfers
Description
SPI transfers always write the same number of bytes as they read.Protocol drivers should always providerx_buf and/ortx_buf.In some cases, they may also want to provide DMA addresses forthe data being transferred; that may reduce overhead, when theunderlying driver uses DMA.
If the transmit buffer is NULL, zeroes will be shifted outwhile fillingrx_buf. If the receive buffer is NULL, the datashifted in will be discarded. Only “len” bytes shift out (or in).It’s an error to try to shift out a partial word. (For example, byshifting out three bytes with word size of sixteen or twenty bits;the former uses two bytes per word, the latter uses four bytes.)
In-memory data values are always in native CPU byte order, translatedfrom the wire byte order (big-endian except with SPI_LSB_FIRST). Sofor example when bits_per_word is sixteen, buffers are 2N bytes long(len = 2N) and hold N sixteen bit words in CPU byte order.
When the word size of the SPI transfer is not a power-of-two multipleof eight bits, those in-memory words include extra bits. In-memorywords are always seen by protocol drivers as right-justified, so theundefined (rx) or unused (tx) bits are always the most significant bits.
All SPI transfers start with the relevant chipselect active. Normallyit stays selected until after the last transfer in a message. Driverscan affect the chipselect signal using cs_change.
(i) If the transfer isn’t the last one in the message, this flag isused to make the chipselect briefly go inactive in the middle of themessage. Toggling chipselect in this way may be needed to terminatea chip command, letting a single spi_message perform all of group ofchip transactions together.
(ii) When the transfer is the last one in the message, the chip maystay selected until the next transfer. On multi-device SPI busseswith nothing blocking messages going to other devices, this is justa performance hint; starting a message to another device deselectsthis one. But in other cases, this can be used to ensure correctness.Some devices need protocol transactions to be built from a series ofspi_message submissions, where the content of one message is determinedby the results of previous messages and where the whole transactionends when the chipselect goes inactive.
When SPI can transfer in 1x,2x or 4x. It can get this transfer informationfrom device throughtx_nbits andrx_nbits. In Bi-direction, thesetwo should both be set. User can set transfer mode with SPI_NBITS_SINGLE(1x)SPI_NBITS_DUAL(2x) and SPI_NBITS_QUAD(4x) to support these three transfer.
User may also set dtr_mode to true to use dual transfer mode if desired. ifnot, default considered as single transfer mode.
The code that submits an spi_message (and its spi_transfers)to the lower layers is responsible for managing its memory.Zero-initialize every field you don’t set up explicitly, toinsulate against future API updates. After you submit a messageand its transfers, ignore them until its completion callback.
- structspi_message¶
one multi-segment SPI transaction
Definition:
struct spi_message { struct list_head transfers; struct spi_device *spi; bool pre_optimized; bool optimized; bool prepared; int status; void (*complete)(void *context); void *context; unsigned frame_length; unsigned actual_length; struct list_head queue; void *state; void *opt_state; struct spi_offload *offload; struct list_head resources;};Members
transferslist of transfer segments in this transaction
spiSPI device to which the transaction is queued
pre_optimizedperipheral driver pre-optimized the message
optimizedthe message is in the optimized state
preparedspi_prepare_message was called for the this message
statuszero for success, else negative errno
completecalled to report transaction completions
contextthe argument to
complete()when it’s calledframe_lengththe total number of bytes in the message
actual_lengththe total number of bytes that were transferred in allsuccessful segments
queuefor use by whichever driver currently owns the message
statefor use by whichever driver currently owns the message
opt_statefor use by whichever driver currently owns the message
offload(optional) offload instance used by this message
resourcesfor resource management when the SPI message is processed
Description
Aspi_message is used to execute an atomic sequence of data transfers,each represented by astructspi_transfer. The sequence is “atomic”in the sense that no other spi_message may use that SPI bus until thatsequence completes. On some systems, many such sequences can execute asa single programmed DMA transfer. On all systems, these messages arequeued, and might complete after transactions to other devices. Messagessent to a given spi_device are always executed in FIFO order.
The code that submits an spi_message (and its spi_transfers)to the lower layers is responsible for managing its memory.Zero-initialize every field you don’t set up explicitly, toinsulate against future API updates. After you submit a messageand its transfers, ignore them until its completion callback.
- voidspi_message_init_with_transfers(structspi_message*m,structspi_transfer*xfers,unsignedintnum_xfers)¶
Initialize spi_message and append transfers
Parameters
structspi_message*mspi_message to be initialized
structspi_transfer*xfersAn array of SPI transfers
unsignedintnum_xfersNumber of items in the xfer array
Description
This function initializes the given spi_message and adds each spi_transfer inthe given array to the message.
- boolspi_is_bpw_supported(structspi_device*spi,u32bpw)¶
Check if bits per word is supported
Parameters
structspi_device*spiSPI device
u32bpwBits per word
Description
This function checks to see if the SPI controller supportsbpw.
Return
True ifbpw is supported, false otherwise.
- u32spi_bpw_to_bytes(u32bpw)¶
Covert bits per word to bytes
Parameters
u32bpwBits per word
Description
This function converts the givenbpw to bytes. The result is alwayspower-of-two, e.g.,
Input (in bits)
Output (in bytes)
5
1
9
2
21
4
37
8
It will return 0 for the 0 input.
Return
Bytes for the givenbpw.
- unsignedintspi_controller_xfer_timeout(structspi_controller*ctlr,structspi_transfer*xfer)¶
Compute a suitable timeout value
Parameters
structspi_controller*ctlrSPI device
structspi_transfer*xferTransfer descriptor
Description
Compute a relevant timeout value for the given transfer. We derive the timethat it would take on a single data line and take twice this amount of timewith a minimum of 500ms to avoid false positives on loaded systems.
Return
Transfer timeout value in milliseconds.
- structspi_replaced_transfers¶
structure describing the spi_transfer replacements that have occurred so that they can get reverted
Definition:
struct spi_replaced_transfers { spi_replaced_release_t release; void *extradata; struct list_head replaced_transfers; struct list_head *replaced_after; size_t inserted; struct spi_transfer inserted_transfers[];};Members
releasesome extra release code to get executed prior toreleasing this structure
extradatapointer to some extra data if requested or NULL
replaced_transferstransfers that have been replaced and which needto get restored
replaced_afterthe transfer after which thereplaced_transfersare to get re-inserted
insertednumber of transfers inserted
inserted_transfersarray of spi_transfers of array-sizeinserted,that have been replacing replaced_transfers
Note
thatextradata will point toinserted_transfers**[**inserted]if some extra allocation is requested, so alignment will be the sameas for spi_transfers.
- intspi_sync_transfer(structspi_device*spi,structspi_transfer*xfers,unsignedintnum_xfers)¶
synchronous SPI data transfer
Parameters
structspi_device*spidevice with which data will be exchanged
structspi_transfer*xfersAn array of spi_transfers
unsignedintnum_xfersNumber of items in the xfer array
Context
can sleep
Description
Does a synchronous SPI data transfer of the given spi_transfer array.
For more specific semantics seespi_sync().
Return
zero on success, else a negative error code.
- intspi_write(structspi_device*spi,constvoid*buf,size_tlen)¶
SPI synchronous write
Parameters
structspi_device*spidevice to which data will be written
constvoid*bufdata buffer
size_tlendata buffer size
Context
can sleep
Description
This function writes the bufferbuf.Callable only from contexts that can sleep.
Return
zero on success, else a negative error code.
- intspi_read(structspi_device*spi,void*buf,size_tlen)¶
SPI synchronous read
Parameters
structspi_device*spidevice from which data will be read
void*bufdata buffer
size_tlendata buffer size
Context
can sleep
Description
This function reads the bufferbuf.Callable only from contexts that can sleep.
Return
zero on success, else a negative error code.
- ssize_tspi_w8r8(structspi_device*spi,u8cmd)¶
SPI synchronous 8 bit write followed by 8 bit read
Parameters
structspi_device*spidevice with which data will be exchanged
u8cmdcommand to be written before data is read back
Context
can sleep
Description
Callable only from contexts that can sleep.
Return
the (unsigned) eight bit number returned by thedevice, or else a negative error code.
- ssize_tspi_w8r16(structspi_device*spi,u8cmd)¶
SPI synchronous 8 bit write followed by 16 bit read
Parameters
structspi_device*spidevice with which data will be exchanged
u8cmdcommand to be written before data is read back
Context
can sleep
Description
The number is returned in wire-order, which is at least sometimesbig-endian.
Callable only from contexts that can sleep.
Return
the (unsigned) sixteen bit number returned by thedevice, or else a negative error code.
- ssize_tspi_w8r16be(structspi_device*spi,u8cmd)¶
SPI synchronous 8 bit write followed by 16 bit big-endian read
Parameters
structspi_device*spidevice with which data will be exchanged
u8cmdcommand to be written before data is read back
Context
can sleep
Description
This function is similar to spi_w8r16, with the exception that it willconvert the read 16 bit data word from big-endian to native endianness.
Callable only from contexts that can sleep.
Return
the (unsigned) sixteen bit number returned by the device in CPUendianness, or else a negative error code.
- structspi_board_info¶
board-specific template for a SPI device
Definition:
struct spi_board_info { char modalias[SPI_NAME_SIZE]; const void *platform_data; const struct software_node *swnode; void *controller_data; int irq; u32 max_speed_hz; u16 bus_num; u16 chip_select; u32 mode;};Members
modaliasInitializes spi_device.modalias; identifies the driver.
platform_dataInitializes spi_device.platform_data; the particulardata stored there is driver-specific.
swnodeSoftware node for the device.
controller_dataInitializes spi_device.controller_data; somecontrollers need hints about hardware setup, e.g. for DMA.
irqInitializes spi_device.irq; depends on how the board is wired.
max_speed_hzInitializes spi_device.max_speed_hz; based on limitsfrom the chip datasheet and board-specific signal quality issues.
bus_numIdentifies which spi_controller parents the spi_device; unusedby
spi_new_device(), and otherwise depends on board wiring.chip_selectInitializes spi_device.chip_select; depends on howthe board is wired.
modeInitializes spi_device.mode; based on the chip datasheet, boardwiring (some devices support both 3WIRE and standard modes), andpossibly presence of an inverter in the chipselect path.
Description
When adding new SPI devices to the device tree, these structures serveas a partial device template. They hold information which can’t alwaysbe determined by drivers. Information thatprobe() can establish (suchas the default transfer wordsize) is not included here.
These structures are used in two places. Their primary role is tobe stored in tables of board-specific device descriptors, which aredeclared early in board initialization and then used (much later) topopulate a controller’s device tree after the that controller’s driverinitializes. A secondary (and atypical) role is as a parameter tospi_new_device() call, which happens after those controller driversare active in some dynamic board configuration models.
- intspi_register_board_info(structspi_board_infoconst*info,unsignedn)¶
register SPI devices for a given board
Parameters
structspi_board_infoconst*infoarray of chip descriptors
unsignednhow many descriptors are provided
Context
can sleep
Description
Board-specific early init code calls this (probably during arch_initcall)with segments of the SPI device table. Any device nodes are created later,after the relevant parent SPI controller (bus_num) is defined. We keepthis table of devices forever, so that reloading a controller driver willnot make Linux forget about these hard-wired devices.
Other code can also call this, e.g. a particular add-on board might provideSPI devices through its expansion connector, so code initializing that boardwould naturally declare its SPI devices.
The board info passed can safely be __initdata ... but be careful ofany embedded pointers (platform_data, etc), they’re copied as-is.
Return
zero on success, else a negative error code.
- int__spi_register_driver(structmodule*owner,structspi_driver*sdrv)¶
register a SPI driver
Parameters
structmodule*ownerowner module of the driver to register
structspi_driver*sdrvthe driver to register
Context
can sleep
Return
zero on success, else a negative error code.
- structspi_device*spi_alloc_device(structspi_controller*ctlr)¶
Allocate a new SPI device
Parameters
structspi_controller*ctlrController to which device is connected
Context
can sleep
Description
Allows a driver to allocate and initialize a spi_device withoutregistering it immediately. This allows a driver to directlyfill the spi_device with device parameters before callingspi_add_device() on it.
Caller is responsible to callspi_add_device() on the returnedspi_device structure to add it to the SPI controller. If the callerneeds to discard the spi_device without adding it, then it shouldcallspi_dev_put() on it.
Return
a pointer to the new device, or NULL.
- intspi_add_device(structspi_device*spi)¶
Add spi_device allocated with spi_alloc_device
Parameters
structspi_device*spispi_device to register
Description
Companion function to spi_alloc_device. Devices allocated withspi_alloc_device can be added onto the SPI bus with this function.
Return
0 on success; negative errno on failure
- structspi_device*spi_new_device(structspi_controller*ctlr,structspi_board_info*chip)¶
instantiate one new SPI device
Parameters
structspi_controller*ctlrController to which device is connected
structspi_board_info*chipDescribes the SPI device
Context
can sleep
Description
On typical mainboards, this is purely internal; and it’s not neededafter board init creates the hard-wired devices. Some developmentplatforms may not be able to use spi_register_board_info though, andthis is exported so that for example a USB or parport based adapterdriver could add devices (which it would learn about out-of-band).
Return
the new device, or NULL.
- voidspi_unregister_device(structspi_device*spi)¶
unregister a single SPI device
Parameters
structspi_device*spispi_device to unregister
Description
Start making the passed SPI device vanish. Normally this would be handledbyspi_unregister_controller().
- voidspi_finalize_current_transfer(structspi_controller*ctlr)¶
report completion of a transfer
Parameters
structspi_controller*ctlrthe controller reporting completion
Description
Called by SPI drivers using the coretransfer_one_message()implementation to notify it that the current interrupt driventransfer has finished and the next one may be scheduled.
- voidspi_take_timestamp_pre(structspi_controller*ctlr,structspi_transfer*xfer,size_tprogress,boolirqs_off)¶
helper to collect the beginning of the TX timestamp
Parameters
structspi_controller*ctlrPointer to the spi_controller structure of the driver
structspi_transfer*xferPointer to the transfer being timestamped
size_tprogressHow many words (not bytes) have been transferred so far
boolirqs_offIf true, will disable IRQs and preemption for the duration of thetransfer, for less jitter in time measurement. Only compatiblewith PIO drivers. If true, must follow up withspi_take_timestamp_post or otherwise system will crash.WARNING: for fully predictable results, the CPU frequency mustalso be under control (governor).
Description
This is a helper for drivers to collect the beginning of the TX timestampfor the requested byte from the SPI transfer. The frequency with which thisfunction must be called (once per word, once for the whole transfer, onceper batch of words etc) is arbitrary as long as thetx buffer offset isgreater than or equal to the requested byte at the time of the call. Thetimestamp is only taken once, at the first such call. It is assumed thatthe driver advances itstx buffer pointer monotonically.
- voidspi_take_timestamp_post(structspi_controller*ctlr,structspi_transfer*xfer,size_tprogress,boolirqs_off)¶
helper to collect the end of the TX timestamp
Parameters
structspi_controller*ctlrPointer to the spi_controller structure of the driver
structspi_transfer*xferPointer to the transfer being timestamped
size_tprogressHow many words (not bytes) have been transferred so far
boolirqs_offIf true, will re-enable IRQs and preemption for the local CPU.
Description
This is a helper for drivers to collect the end of the TX timestamp forthe requested byte from the SPI transfer. Can be called with an arbitraryfrequency: only the first call wheretx exceeds or is equal to therequested word will be timestamped.
- structspi_message*spi_get_next_queued_message(structspi_controller*ctlr)¶
called by driver to check for queued messages
Parameters
structspi_controller*ctlrthe controller to check for queued messages
Description
If there are more messages in the queue, the next message is returned fromthis call.
Return
the next message in the queue, else NULL if the queue is empty.
- voidspi_finalize_current_message(structspi_controller*ctlr)¶
the current message is complete
Parameters
structspi_controller*ctlrthe controller to return the message to
Description
Called by the driver to notify the core that the message in the front of thequeue is complete and can be removed from the queue.
- structspi_device*spi_new_ancillary_device(structspi_device*spi,u8chip_select)¶
Register ancillary SPI device
Parameters
structspi_device*spiPointer to the main SPI device registering the ancillary device
u8chip_selectChip Select of the ancillary device
Description
Register an ancillary SPI device; for example some chips have a chip-selectfor normal device usage and another one for setup/firmware upload.
This may only be called from main SPI device’s probe routine.
Return
0 on success; negative errno on failure
- intacpi_spi_count_resources(structacpi_device*adev)¶
Count the number of SpiSerialBus resources
Parameters
structacpi_device*adevACPI device
Return
the number of SpiSerialBus resources in the ACPI-device’sresource-list; or a negative error code.
- structspi_device*acpi_spi_device_alloc(structspi_controller*ctlr,structacpi_device*adev,intindex)¶
Allocate a spi device, and fill it in with ACPI information
Parameters
structspi_controller*ctlrcontroller to which the spi device belongs
structacpi_device*adevACPI Device for the spi device
intindexIndex of the spi resource inside the ACPI Node
Description
This should be used to allocate a new SPI device from and ACPI Device node.The caller is responsible for calling spi_add_device to register the SPI device.
If ctlr is set to NULL, the Controller for the SPI device will be looked upusing the resource.If index is set to -1, index is not used.
Note
If index is -1, ctlr must be set.
Return
a pointer to the new device, or ERR_PTR on error.
- intspi_target_abort(structspi_device*spi)¶
abort the ongoing transfer request on an SPI target controller
Parameters
structspi_device*spidevice used for the current transfer
- structspi_controller*__spi_alloc_controller(structdevice*dev,unsignedintsize,booltarget)¶
allocate an SPI host or target controller
Parameters
structdevice*devthe controller, possibly using the platform_bus
unsignedintsizehow much zeroed driver-private data to allocate; the pointer to thismemory is in the driver_data field of the returned device, accessiblewith
spi_controller_get_devdata(); the memory is cacheline aligned;drivers granting DMA access to portions of their private data need toround upsize using ALIGN(size,dma_get_cache_alignment()).booltargetflag indicating whether to allocate an SPI host (false) or SPI target (true)controller
Context
can sleep
Description
This call is used only by SPI controller drivers, which are theonly ones directly touching chip registers. It’s how they allocatean spi_controller structure, prior to callingspi_register_controller().
This must be called from context that can sleep.
The caller is responsible for assigning the bus number and initializing thecontroller’s methods before callingspi_register_controller(); and (aftererrors adding the device) callingspi_controller_put() to prevent a memoryleak.
Return
the SPI controller structure on success, else NULL.
- structspi_controller*__devm_spi_alloc_controller(structdevice*dev,unsignedintsize,booltarget)¶
resource-managed
__spi_alloc_controller()
Parameters
structdevice*devphysical device of SPI controller
unsignedintsizehow much zeroed driver-private data to allocate
booltargetwhether to allocate an SPI host (false) or SPI target (true) controller
Context
can sleep
Description
Allocate an SPI controller and automatically release a reference on itwhendev is unbound from its driver. Drivers are thus relieved fromhaving to callspi_controller_put().
The arguments to this function are identical to__spi_alloc_controller().
Return
the SPI controller structure on success, else NULL.
- intspi_register_controller(structspi_controller*ctlr)¶
register SPI host or target controller
Parameters
structspi_controller*ctlrinitialized controller, originally from
spi_alloc_host()orspi_alloc_target()
Context
can sleep
Description
SPI controllers connect to their drivers using some non-SPI bus,such as the platform bus. The final stage ofprobe() in that codeincludes callingspi_register_controller() to hook up to this SPI bus glue.
SPI controllers use board specific (often SOC specific) bus numbers,and board-specific addressing for SPI devices combines those numberswith chip select numbers. Since SPI does not directly support dynamicdevice identification, boards need configuration tables telling whichchip is at which address.
This must be called from context that can sleep. It returns zero onsuccess, else a negative error code (dropping the controller’s refcount).After a successful return, the caller is responsible for callingspi_unregister_controller().
Return
zero on success, else a negative error code.
- intdevm_spi_register_controller(structdevice*dev,structspi_controller*ctlr)¶
register managed SPI host or target controller
Parameters
structdevice*devdevice managing SPI controller
structspi_controller*ctlrinitialized controller, originally from
spi_alloc_host()orspi_alloc_target()
Context
can sleep
Description
Register a SPI device as withspi_register_controller() which willautomatically be unregistered and freed.
Return
zero on success, else a negative error code.
- voidspi_unregister_controller(structspi_controller*ctlr)¶
unregister SPI host or target controller
Parameters
structspi_controller*ctlrthe controller being unregistered
Context
can sleep
Description
This call is used only by SPI controller drivers, which are theonly ones directly touching chip registers.
This must be called from context that can sleep.
Note that this function also drops a reference to the controller.
- intspi_split_transfers_maxsize(structspi_controller*ctlr,structspi_message*msg,size_tmaxsize)¶
split spi transfers into multiple transfers when an individual transfer exceeds a certain size
Parameters
structspi_controller*ctlrthespi_controller for this transfer
structspi_message*msgthespi_message to transform
size_tmaxsizethe maximum when to apply this
Description
This function allocates resources that are automatically freed during thespi message unoptimize phase so this function should only be called fromoptimize_message callbacks.
Return
status of transformation
- intspi_split_transfers_maxwords(structspi_controller*ctlr,structspi_message*msg,size_tmaxwords)¶
split SPI transfers into multiple transfers when an individual transfer exceeds a certain number of SPI words
Parameters
structspi_controller*ctlrthespi_controller for this transfer
structspi_message*msgthespi_message to transform
size_tmaxwordsthe number of words to limit each transfer to
Description
This function allocates resources that are automatically freed during thespi message unoptimize phase so this function should only be called fromoptimize_message callbacks.
Return
status of transformation
- intspi_setup(structspi_device*spi)¶
setup SPI mode and clock rate
Parameters
structspi_device*spithe device whose settings are being modified
Context
can sleep, and no requests are queued to the device
Description
SPI protocol drivers may need to update the transfer mode if thedevice doesn’t work with its default. They may likewise needto update clock rates or word sizes from initial values. This functionchanges those settings, and must be called from a context that can sleep.Except for SPI_CS_HIGH, which takes effect immediately, the changes takeeffect the next time the device is selected and data is transferred toor from it. When this function returns, the SPI device is deselected.
Note that this call will fail if the protocol driver specifies an optionthat the underlying controller or its driver does not support. Forexample, not all hardware supports wire transfers using nine bit words,LSB-first wire encoding, or active-high chipselects.
Return
zero on success, else a negative error code.
- intspi_optimize_message(structspi_device*spi,structspi_message*msg)¶
do any one-time validation and setup for a SPI message
Parameters
structspi_device*spithe device that will be used for the message
structspi_message*msgthe message to optimize
Description
Peripheral drivers that reuse the same message repeatedly may call this toperform as much message prep as possible once, rather than repeating it eachtime a message transfer is performed to improve throughput and reduce CPUusage.
Once a message has been optimized, it cannot be modified with the exceptionof updating the contents of any xfer->tx_buf (the pointer can’t be changed,only the data in the memory it points to).
Calls to this function must be balanced with calls tospi_unoptimize_message()to avoid leaking resources.
Context
can sleep
Return
zero on success, else a negative error code
- voidspi_unoptimize_message(structspi_message*msg)¶
releases any resources allocated by
spi_optimize_message()
Parameters
structspi_message*msgthe message to unoptimize
Description
Calls to this function must be balanced with calls tospi_optimize_message().
Context
can sleep
- intdevm_spi_optimize_message(structdevice*dev,structspi_device*spi,structspi_message*msg)¶
managed version of
spi_optimize_message()
Parameters
structdevice*devthe device that managesmsg (usuallyspi->dev)
structspi_device*spithe device that will be used for the message
structspi_message*msgthe message to optimize
Return
zero on success, else a negative error code
Description
spi_unoptimize_message() will automatically be called when the device isremoved.
- intspi_async(structspi_device*spi,structspi_message*message)¶
asynchronous SPI transfer
Parameters
structspi_device*spidevice with which data will be exchanged
structspi_message*messagedescribes the data transfers, including completion callback
Context
any (IRQs may be blocked, etc)
Description
This call may be used in_irq and other contexts which can’t sleep,as well as from task contexts which can sleep.
The completion callback is invoked in a context which can’t sleep.Before that invocation, the value of message->status is undefined.When the callback is issued, message->status holds either zero (toindicate complete success) or a negative error code. After thatcallback returns, the driver which issued the transfer request maydeallocate the associated memory; it’s no longer in use by any SPIcore or controller driver code.
Note that although all messages to a spi_device are handled inFIFO order, messages may go to different devices in other orders.Some device might be higher priority, or have various “hard” accesstime requirements, for example.
On detection of any fault during the transfer, processing ofthe entire message is aborted, and the device is deselected.Until returning from the associated message completion callback,no other spi_message queued to that device will be processed.(This rule applies equally to all the synchronous transfer calls,which are wrappers around this core asynchronous primitive.)
Return
zero on success, else a negative error code.
- intspi_sync(structspi_device*spi,structspi_message*message)¶
blocking/synchronous SPI data transfers
Parameters
structspi_device*spidevice with which data will be exchanged
structspi_message*messagedescribes the data transfers
Context
can sleep
Description
This call may only be used from a context that may sleep. The sleepis non-interruptible, and has no timeout. Low-overhead controllerdrivers may DMA directly into and out of the message buffers.
Note that the SPI device’s chip select is active during the message,and then is normally disabled between messages. Drivers for somefrequently-used devices may want to minimize costs of selecting a chip,by leaving it selected in anticipation that the next message will goto the same chip. (That may increase power usage.)
Also, the caller is guaranteeing that the memory associated with themessage will not be freed before this call returns.
Return
zero on success, else a negative error code.
- intspi_sync_locked(structspi_device*spi,structspi_message*message)¶
version of spi_sync with exclusive bus usage
Parameters
structspi_device*spidevice with which data will be exchanged
structspi_message*messagedescribes the data transfers
Context
can sleep
Description
This call may only be used from a context that may sleep. The sleepis non-interruptible, and has no timeout. Low-overhead controllerdrivers may DMA directly into and out of the message buffers.
This call should be used by drivers that require exclusive access to theSPI bus. It has to be preceded by a spi_bus_lock call. The SPI bus mustbe released by a spi_bus_unlock call when the exclusive access is over.
Return
zero on success, else a negative error code.
- intspi_bus_lock(structspi_controller*ctlr)¶
obtain a lock for exclusive SPI bus usage
Parameters
structspi_controller*ctlrSPI bus controller that should be locked for exclusive bus access
Context
can sleep
Description
This call may only be used from a context that may sleep. The sleepis non-interruptible, and has no timeout.
This call should be used by drivers that require exclusive access to theSPI bus. The SPI bus must be released by a spi_bus_unlock call when theexclusive access is over. Data transfer must be done by spi_sync_lockedand spi_async_locked calls when the SPI bus lock is held.
Return
always zero.
- intspi_bus_unlock(structspi_controller*ctlr)¶
release the lock for exclusive SPI bus usage
Parameters
structspi_controller*ctlrSPI bus controller that was locked for exclusive bus access
Context
can sleep
Description
This call may only be used from a context that may sleep. The sleepis non-interruptible, and has no timeout.
This call releases an SPI bus lock previously obtained by an spi_bus_lockcall.
Return
always zero.
- intspi_write_then_read(structspi_device*spi,constvoid*txbuf,unsignedn_tx,void*rxbuf,unsignedn_rx)¶
SPI synchronous write followed by read
Parameters
structspi_device*spidevice with which data will be exchanged
constvoid*txbufdata to be written (need not be DMA-safe)
unsignedn_txsize of txbuf, in bytes
void*rxbufbuffer into which data will be read (need not be DMA-safe)
unsignedn_rxsize of rxbuf, in bytes
Context
can sleep
Description
This performs a half duplex MicroWire style transaction with thedevice, sending txbuf and then reading rxbuf. The return valueis zero for success, else a negative errno status code.This call may only be used from a context that may sleep.
Parameters to this routine are always copied using a small buffer.Performance-sensitive or bulk transfer code should instead usespi_{async,sync}() calls with DMA-safe buffers.
Return
zero on success, else a negative error code.