- It may also be used to stream data in either direction (half duplex),
or both of them at the same time (full duplex).
- - Some devices may use eight bit words. Others may different word
+ - Some devices may use eight bit words. Others may use different word
lengths, such as streams of 12-bit or 20-bit digital samples.
- Words are usually sent with their most significant bit (MSB) first,
a slave, and the slave can tell the chosen polarity by sampling the
clock level when its select line goes active. That's why many devices
support for example both modes 0 and 3: they don't care about polarity,
-and alway clock data in/out on rising clock edges.
+and always clock data in/out on rising clock edges.
How do these driver programming interfaces work?
There are two types of SPI driver, here called:
- Controller drivers ... controllers may be built in to System-On-Chip
+ Controller drivers ... controllers may be built into System-On-Chip
processors, and often support both Master and Slave roles.
These drivers touch hardware registers and may use DMA.
Or they can be PIO bitbangers, needing just GPIO pins.
DEPRECATED METHODS
master->transfer(struct spi_device *spi, struct spi_message *message)
- This must not sleep. Its responsibility is arrange that the
+ This must not sleep. Its responsibility is to arrange that the
transfer happens and its complete() callback is issued. The two
will normally happen later, after other transfers complete, and
if the controller is idle it will need to be kickstarted. This
}
/* Extract head of queue */
master->cur_msg =
- list_entry(master->queue.next, struct spi_message, queue);
+ list_first_entry(&master->queue, struct spi_message, queue);
list_del_init(&master->cur_msg->queue);
if (master->busy)
/* get a pointer to the next message, if any */
spin_lock_irqsave(&master->queue_lock, flags);
- if (list_empty(&master->queue))
- next = NULL;
- else
- next = list_entry(master->queue.next,
- struct spi_message, queue);
+ next = list_first_entry_or_null(&master->queue, struct spi_message,
+ queue);
spin_unlock_irqrestore(&master->queue_lock, flags);
return next;
}
EXPORT_SYMBOL_GPL(spi_setup);
-static int __spi_async(struct spi_device *spi, struct spi_message *message)
+static int __spi_validate(struct spi_device *spi, struct spi_message *message)
{
struct spi_master *master = spi->master;
struct spi_transfer *xfer;
- message->spi = spi;
-
- trace_spi_message_submit(message);
-
if (list_empty(&message->transfers))
return -EINVAL;
if (!message->complete)
if (xfer->rx_buf && !xfer->rx_nbits)
xfer->rx_nbits = SPI_NBITS_SINGLE;
/* check transfer tx/rx_nbits:
- * 1. keep the value is not out of single, dual and quad
- * 2. keep tx/rx_nbits is contained by mode in spi_device
- * 3. if SPI_3WIRE, tx/rx_nbits should be in single
+ * 1. check the value matches one of single, dual and quad
+ * 2. check tx/rx_nbits match the mode in spi_device
*/
if (xfer->tx_buf) {
if (xfer->tx_nbits != SPI_NBITS_SINGLE &&
if ((xfer->tx_nbits == SPI_NBITS_QUAD) &&
!(spi->mode & SPI_TX_QUAD))
return -EINVAL;
- if ((spi->mode & SPI_3WIRE) &&
- (xfer->tx_nbits != SPI_NBITS_SINGLE))
- return -EINVAL;
}
/* check transfer rx_nbits */
if (xfer->rx_buf) {
if ((xfer->rx_nbits == SPI_NBITS_QUAD) &&
!(spi->mode & SPI_RX_QUAD))
return -EINVAL;
- if ((spi->mode & SPI_3WIRE) &&
- (xfer->rx_nbits != SPI_NBITS_SINGLE))
- return -EINVAL;
}
}
message->status = -EINPROGRESS;
+
+ return 0;
+}
+
+static int __spi_async(struct spi_device *spi, struct spi_message *message)
+{
+ struct spi_master *master = spi->master;
+
+ message->spi = spi;
+
+ trace_spi_message_submit(message);
+
return master->transfer(spi, message);
}
int ret;
unsigned long flags;
+ ret = __spi_validate(spi, message);
+ if (ret != 0)
+ return ret;
+
spin_lock_irqsave(&master->bus_lock_spinlock, flags);
if (master->bus_lock_flag)
int ret;
unsigned long flags;
+ ret = __spi_validate(spi, message);
+ if (ret != 0)
+ return ret;
+
spin_lock_irqsave(&master->bus_lock_spinlock, flags);
ret = __spi_async(spi, message);
struct spi_master *master;
u32 max_speed_hz;
u8 chip_select;
+ u8 bits_per_word;
u16 mode;
#define SPI_CPHA 0x01 /* clock phase */
#define SPI_CPOL 0x02 /* clock polarity */
#define SPI_TX_QUAD 0x200 /* transmit with 4 wires */
#define SPI_RX_DUAL 0x400 /* receive with 2 wires */
#define SPI_RX_QUAD 0x800 /* receive with 4 wires */
- u8 bits_per_word;
int irq;
void *controller_state;
void *controller_data;
dma_addr_t rx_dma;
unsigned cs_change:1;
- u8 tx_nbits;
- u8 rx_nbits;
+ unsigned tx_nbits:3;
+ unsigned rx_nbits:3;
#define SPI_NBITS_SINGLE 0x01 /* 1bit transfer */
#define SPI_NBITS_DUAL 0x02 /* 2bits transfer */
#define SPI_NBITS_QUAD 0x04 /* 4bits transfer */
ssize_t status;
u16 result;
- status = spi_write_then_read(spi, &cmd, 1, (u8 *) &result, 2);
+ status = spi_write_then_read(spi, &cmd, 1, &result, 2);
/* return negative errno or unsigned value */
return (status < 0) ? status : result;