Loading drivers/spi/spi.c +30 −1 Original line number Diff line number Diff line Loading @@ -2774,8 +2774,10 @@ int spi_setup(struct spi_device *spi) return -EINVAL; /* help drivers fail *cleanly* when they need options * that aren't supported with their current controller * SPI_CS_WORD has a fallback software implementation, * so it is ignored here. */ bad_bits = spi->mode & ~spi->controller->mode_bits; bad_bits = spi->mode & ~(spi->controller->mode_bits | SPI_CS_WORD); ugly_bits = bad_bits & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD); if (ugly_bits) { Loading Loading @@ -2829,6 +2831,33 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) if (list_empty(&message->transfers)) return -EINVAL; /* If an SPI controller does not support toggling the CS line on each * transfer (indicated by the SPI_CS_WORD flag), we can emulate it by * splitting transfers into one-word transfers and ensuring that * cs_change is set for each transfer. */ if ((spi->mode & SPI_CS_WORD) && !(ctlr->mode_bits & SPI_CS_WORD)) { size_t maxsize; int ret; maxsize = (spi->bits_per_word + 7) / 8; /* spi_split_transfers_maxsize() requires message->spi */ message->spi = spi; ret = spi_split_transfers_maxsize(ctlr, message, maxsize, GFP_KERNEL); if (ret) return ret; list_for_each_entry(xfer, &message->transfers, transfer_list) { /* don't change cs_change on the last entry in the list */ if (list_is_last(&xfer->transfer_list, &message->transfers)) break; xfer->cs_change = 1; } } /* Half-duplex links include original MicroWire, and ones with * only one data pin like SPI_3WIRE (switches direction) or where * either MOSI or MISO is missing. They can also be caused by Loading include/linux/spi/spi.h +1 −1 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ struct spi_device { #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 */ #define SPI_CS_WORD 0x1000 /* toggle cs after each word */ int irq; void *controller_state; void *controller_data; Loading @@ -177,7 +178,6 @@ struct spi_device { * the controller talks to each chip, like: * - memory packing (12 bit samples into low bits, others zeroed) * - priority * - drop chipselect after each word * - chipselect delays * - ... */ Loading Loading
drivers/spi/spi.c +30 −1 Original line number Diff line number Diff line Loading @@ -2774,8 +2774,10 @@ int spi_setup(struct spi_device *spi) return -EINVAL; /* help drivers fail *cleanly* when they need options * that aren't supported with their current controller * SPI_CS_WORD has a fallback software implementation, * so it is ignored here. */ bad_bits = spi->mode & ~spi->controller->mode_bits; bad_bits = spi->mode & ~(spi->controller->mode_bits | SPI_CS_WORD); ugly_bits = bad_bits & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD); if (ugly_bits) { Loading Loading @@ -2829,6 +2831,33 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) if (list_empty(&message->transfers)) return -EINVAL; /* If an SPI controller does not support toggling the CS line on each * transfer (indicated by the SPI_CS_WORD flag), we can emulate it by * splitting transfers into one-word transfers and ensuring that * cs_change is set for each transfer. */ if ((spi->mode & SPI_CS_WORD) && !(ctlr->mode_bits & SPI_CS_WORD)) { size_t maxsize; int ret; maxsize = (spi->bits_per_word + 7) / 8; /* spi_split_transfers_maxsize() requires message->spi */ message->spi = spi; ret = spi_split_transfers_maxsize(ctlr, message, maxsize, GFP_KERNEL); if (ret) return ret; list_for_each_entry(xfer, &message->transfers, transfer_list) { /* don't change cs_change on the last entry in the list */ if (list_is_last(&xfer->transfer_list, &message->transfers)) break; xfer->cs_change = 1; } } /* Half-duplex links include original MicroWire, and ones with * only one data pin like SPI_3WIRE (switches direction) or where * either MOSI or MISO is missing. They can also be caused by Loading
include/linux/spi/spi.h +1 −1 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ struct spi_device { #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 */ #define SPI_CS_WORD 0x1000 /* toggle cs after each word */ int irq; void *controller_state; void *controller_data; Loading @@ -177,7 +178,6 @@ struct spi_device { * the controller talks to each chip, like: * - memory packing (12 bit samples into low bits, others zeroed) * - priority * - drop chipselect after each word * - chipselect delays * - ... */ Loading