Loading drivers/spi/spi.c +118 −1 Original line number Diff line number Diff line Loading @@ -885,6 +885,51 @@ static void of_register_spi_devices(struct spi_master *master) if (of_find_property(nc, "spi-3wire", NULL)) spi->mode |= SPI_3WIRE; /* Device DUAL/QUAD mode */ prop = of_get_property(nc, "spi-tx-nbits", &len); if (!prop || len < sizeof(*prop)) { dev_err(&master->dev, "%s has no 'spi-tx-nbits' property\n", nc->full_name); spi_dev_put(spi); continue; } switch (be32_to_cpup(prop)) { case SPI_NBITS_SINGLE: break; case SPI_NBITS_DUAL: spi->mode |= SPI_TX_DUAL; break; case SPI_NBITS_QUAD: spi->mode |= SPI_TX_QUAD; break; default: dev_err(&master->dev, "spi-tx-nbits value is not supported\n"); spi_dev_put(spi); continue; } prop = of_get_property(nc, "spi-rx-nbits", &len); if (!prop || len < sizeof(*prop)) { dev_err(&master->dev, "%s has no 'spi-rx-nbits' property\n", nc->full_name); spi_dev_put(spi); continue; } switch (be32_to_cpup(prop)) { case SPI_NBITS_SINGLE: break; case SPI_NBITS_DUAL: spi->mode |= SPI_RX_DUAL; break; case SPI_NBITS_QUAD: spi->mode |= SPI_RX_QUAD; break; default: dev_err(&master->dev, "spi-rx-nbits value is not supported\n"); spi_dev_put(spi); continue; } /* Device speed */ prop = of_get_property(nc, "spi-max-frequency", &len); if (!prop || len < sizeof(*prop)) { Loading Loading @@ -1332,6 +1377,19 @@ int spi_setup(struct spi_device *spi) unsigned bad_bits; int status = 0; /* check mode to prevent that DUAL and QUAD set at the same time */ if (((spi->mode & SPI_TX_DUAL) && (spi->mode & SPI_TX_QUAD)) || ((spi->mode & SPI_RX_DUAL) && (spi->mode & SPI_RX_QUAD))) { dev_err(&spi->dev, "setup: can not select dual and quad at the same time\n"); return -EINVAL; } /* if it is SPI_3WIRE mode, DUAL and QUAD should be forbidden */ if ((spi->mode & SPI_3WIRE) && (spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD))) return -EINVAL; /* help drivers fail *cleanly* when they need options * that aren't supported with their current master */ Loading Loading @@ -1367,6 +1425,11 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) struct spi_master *master = spi->master; struct spi_transfer *xfer; if (list_empty(&message->transfers)) return -EINVAL; if (!message->complete) return -EINVAL; /* 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 @@ -1389,12 +1452,19 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) /** * Set transfer bits_per_word and max speed as spi device default if * it is not set for this transfer. * Set transfer tx_nbits and rx_nbits as single transfer default * (SPI_NBITS_SINGLE) if it is not set for this transfer. */ list_for_each_entry(xfer, &message->transfers, transfer_list) { if (!xfer->bits_per_word) xfer->bits_per_word = spi->bits_per_word; if (!xfer->speed_hz) if (!xfer->speed_hz) { xfer->speed_hz = spi->max_speed_hz; if (master->max_speed_hz && xfer->speed_hz > master->max_speed_hz) xfer->speed_hz = master->max_speed_hz; } if (master->bits_per_word_mask) { /* Only 32 bits fit in the mask */ if (xfer->bits_per_word > 32) Loading @@ -1403,6 +1473,53 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) BIT(xfer->bits_per_word - 1))) return -EINVAL; } if (xfer->speed_hz && master->min_speed_hz && xfer->speed_hz < master->min_speed_hz) return -EINVAL; if (xfer->speed_hz && master->max_speed_hz && xfer->speed_hz > master->max_speed_hz) if (xfer->tx_buf && !xfer->tx_nbits) xfer->tx_nbits = SPI_NBITS_SINGLE; 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 */ if (xfer->tx_buf) { if (xfer->tx_nbits != SPI_NBITS_SINGLE && xfer->tx_nbits != SPI_NBITS_DUAL && xfer->tx_nbits != SPI_NBITS_QUAD) return -EINVAL; if ((xfer->tx_nbits == SPI_NBITS_DUAL) && !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD))) return -EINVAL; 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_SINGLE && xfer->rx_nbits != SPI_NBITS_DUAL && xfer->rx_nbits != SPI_NBITS_QUAD) return -EINVAL; if ((xfer->rx_nbits == SPI_NBITS_DUAL) && !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD))) return -EINVAL; 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->spi = spi; Loading include/linux/spi/spi.h +26 −2 Original line number Diff line number Diff line Loading @@ -74,7 +74,7 @@ struct spi_device { struct spi_master *master; u32 max_speed_hz; u8 chip_select; u8 mode; u16 mode; #define SPI_CPHA 0x01 /* clock phase */ #define SPI_CPOL 0x02 /* clock polarity */ #define SPI_MODE_0 (0|0) /* (original MicroWire) */ Loading @@ -87,6 +87,10 @@ struct spi_device { #define SPI_LOOP 0x20 /* loopback mode */ #define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */ #define SPI_READY 0x80 /* slave pulls low to pause */ #define SPI_TX_DUAL 0x100 /* transmit with 2 wires */ #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; Loading Loading @@ -233,6 +237,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * suported. If set, the SPI core will reject any transfer with an * unsupported 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_hz: Lowest supported transfer speed * @max_speed_hz: Highest supported transfer speed * @flags: other constraints relevant to this driver * @bus_lock_spinlock: spinlock for SPI bus locking * @bus_lock_mutex: mutex for SPI bus locking Loading Loading @@ -315,6 +321,10 @@ struct spi_master { #define SPI_BIT_MASK(bits) (((bits) == 32) ? ~0UL : (BIT(bits) - 1)) #define SPI_BPW_RANGE_MASK(min, max) (SPI_BIT_MASK(max) - SPI_BIT_MASK(min - 1)) /* limits on transfer speed */ u32 min_speed_hz; u32 max_speed_hz; /* other constraints relevant to this driver */ u16 flags; #define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */ Loading Loading @@ -453,6 +463,10 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); * @rx_buf: data to be read (dma-safe memory), or NULL * @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped * @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped * @tx_nbits: number of bits used for writting. If 0 the default * (SPI_NBITS_SINGLE) is used. * @rx_nbits: number of bits used for reading. If 0 the default * (SPI_NBITS_SINGLE) is used. * @len: size of rx and tx buffers (in bytes) * @speed_hz: Select a speed other than the device default for this * transfer. If 0 the default (from @spi_device) is used. Loading Loading @@ -507,6 +521,11 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); * by the results of previous messages and where the whole transaction * ends when the chipselect goes intactive. * * When SPI can transfer in 1x,2x or 4x. It can get this tranfer information * from device through @tx_nbits and @rx_nbits. In Bi-direction, these * two 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. * * 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, to Loading @@ -527,6 +546,11 @@ struct spi_transfer { dma_addr_t rx_dma; unsigned cs_change:1; u8 tx_nbits; u8 rx_nbits; #define SPI_NBITS_SINGLE 0x01 /* 1bit transfer */ #define SPI_NBITS_DUAL 0x02 /* 2bits transfer */ #define SPI_NBITS_QUAD 0x04 /* 4bits transfer */ u8 bits_per_word; u16 delay_usecs; u32 speed_hz; Loading Loading @@ -874,7 +898,7 @@ struct spi_board_info { /* mode becomes spi_device.mode, and is essential for chips * where the default of SPI_CS_HIGH = 0 is wrong. */ u8 mode; u16 mode; /* ... may need additional spi_device chip config data here. * avoid stuff protocol drivers can set; but include stuff Loading Loading
drivers/spi/spi.c +118 −1 Original line number Diff line number Diff line Loading @@ -885,6 +885,51 @@ static void of_register_spi_devices(struct spi_master *master) if (of_find_property(nc, "spi-3wire", NULL)) spi->mode |= SPI_3WIRE; /* Device DUAL/QUAD mode */ prop = of_get_property(nc, "spi-tx-nbits", &len); if (!prop || len < sizeof(*prop)) { dev_err(&master->dev, "%s has no 'spi-tx-nbits' property\n", nc->full_name); spi_dev_put(spi); continue; } switch (be32_to_cpup(prop)) { case SPI_NBITS_SINGLE: break; case SPI_NBITS_DUAL: spi->mode |= SPI_TX_DUAL; break; case SPI_NBITS_QUAD: spi->mode |= SPI_TX_QUAD; break; default: dev_err(&master->dev, "spi-tx-nbits value is not supported\n"); spi_dev_put(spi); continue; } prop = of_get_property(nc, "spi-rx-nbits", &len); if (!prop || len < sizeof(*prop)) { dev_err(&master->dev, "%s has no 'spi-rx-nbits' property\n", nc->full_name); spi_dev_put(spi); continue; } switch (be32_to_cpup(prop)) { case SPI_NBITS_SINGLE: break; case SPI_NBITS_DUAL: spi->mode |= SPI_RX_DUAL; break; case SPI_NBITS_QUAD: spi->mode |= SPI_RX_QUAD; break; default: dev_err(&master->dev, "spi-rx-nbits value is not supported\n"); spi_dev_put(spi); continue; } /* Device speed */ prop = of_get_property(nc, "spi-max-frequency", &len); if (!prop || len < sizeof(*prop)) { Loading Loading @@ -1332,6 +1377,19 @@ int spi_setup(struct spi_device *spi) unsigned bad_bits; int status = 0; /* check mode to prevent that DUAL and QUAD set at the same time */ if (((spi->mode & SPI_TX_DUAL) && (spi->mode & SPI_TX_QUAD)) || ((spi->mode & SPI_RX_DUAL) && (spi->mode & SPI_RX_QUAD))) { dev_err(&spi->dev, "setup: can not select dual and quad at the same time\n"); return -EINVAL; } /* if it is SPI_3WIRE mode, DUAL and QUAD should be forbidden */ if ((spi->mode & SPI_3WIRE) && (spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD))) return -EINVAL; /* help drivers fail *cleanly* when they need options * that aren't supported with their current master */ Loading Loading @@ -1367,6 +1425,11 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) struct spi_master *master = spi->master; struct spi_transfer *xfer; if (list_empty(&message->transfers)) return -EINVAL; if (!message->complete) return -EINVAL; /* 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 @@ -1389,12 +1452,19 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) /** * Set transfer bits_per_word and max speed as spi device default if * it is not set for this transfer. * Set transfer tx_nbits and rx_nbits as single transfer default * (SPI_NBITS_SINGLE) if it is not set for this transfer. */ list_for_each_entry(xfer, &message->transfers, transfer_list) { if (!xfer->bits_per_word) xfer->bits_per_word = spi->bits_per_word; if (!xfer->speed_hz) if (!xfer->speed_hz) { xfer->speed_hz = spi->max_speed_hz; if (master->max_speed_hz && xfer->speed_hz > master->max_speed_hz) xfer->speed_hz = master->max_speed_hz; } if (master->bits_per_word_mask) { /* Only 32 bits fit in the mask */ if (xfer->bits_per_word > 32) Loading @@ -1403,6 +1473,53 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) BIT(xfer->bits_per_word - 1))) return -EINVAL; } if (xfer->speed_hz && master->min_speed_hz && xfer->speed_hz < master->min_speed_hz) return -EINVAL; if (xfer->speed_hz && master->max_speed_hz && xfer->speed_hz > master->max_speed_hz) if (xfer->tx_buf && !xfer->tx_nbits) xfer->tx_nbits = SPI_NBITS_SINGLE; 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 */ if (xfer->tx_buf) { if (xfer->tx_nbits != SPI_NBITS_SINGLE && xfer->tx_nbits != SPI_NBITS_DUAL && xfer->tx_nbits != SPI_NBITS_QUAD) return -EINVAL; if ((xfer->tx_nbits == SPI_NBITS_DUAL) && !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD))) return -EINVAL; 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_SINGLE && xfer->rx_nbits != SPI_NBITS_DUAL && xfer->rx_nbits != SPI_NBITS_QUAD) return -EINVAL; if ((xfer->rx_nbits == SPI_NBITS_DUAL) && !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD))) return -EINVAL; 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->spi = spi; Loading
include/linux/spi/spi.h +26 −2 Original line number Diff line number Diff line Loading @@ -74,7 +74,7 @@ struct spi_device { struct spi_master *master; u32 max_speed_hz; u8 chip_select; u8 mode; u16 mode; #define SPI_CPHA 0x01 /* clock phase */ #define SPI_CPOL 0x02 /* clock polarity */ #define SPI_MODE_0 (0|0) /* (original MicroWire) */ Loading @@ -87,6 +87,10 @@ struct spi_device { #define SPI_LOOP 0x20 /* loopback mode */ #define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */ #define SPI_READY 0x80 /* slave pulls low to pause */ #define SPI_TX_DUAL 0x100 /* transmit with 2 wires */ #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; Loading Loading @@ -233,6 +237,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * suported. If set, the SPI core will reject any transfer with an * unsupported 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_hz: Lowest supported transfer speed * @max_speed_hz: Highest supported transfer speed * @flags: other constraints relevant to this driver * @bus_lock_spinlock: spinlock for SPI bus locking * @bus_lock_mutex: mutex for SPI bus locking Loading Loading @@ -315,6 +321,10 @@ struct spi_master { #define SPI_BIT_MASK(bits) (((bits) == 32) ? ~0UL : (BIT(bits) - 1)) #define SPI_BPW_RANGE_MASK(min, max) (SPI_BIT_MASK(max) - SPI_BIT_MASK(min - 1)) /* limits on transfer speed */ u32 min_speed_hz; u32 max_speed_hz; /* other constraints relevant to this driver */ u16 flags; #define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */ Loading Loading @@ -453,6 +463,10 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); * @rx_buf: data to be read (dma-safe memory), or NULL * @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped * @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped * @tx_nbits: number of bits used for writting. If 0 the default * (SPI_NBITS_SINGLE) is used. * @rx_nbits: number of bits used for reading. If 0 the default * (SPI_NBITS_SINGLE) is used. * @len: size of rx and tx buffers (in bytes) * @speed_hz: Select a speed other than the device default for this * transfer. If 0 the default (from @spi_device) is used. Loading Loading @@ -507,6 +521,11 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); * by the results of previous messages and where the whole transaction * ends when the chipselect goes intactive. * * When SPI can transfer in 1x,2x or 4x. It can get this tranfer information * from device through @tx_nbits and @rx_nbits. In Bi-direction, these * two 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. * * 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, to Loading @@ -527,6 +546,11 @@ struct spi_transfer { dma_addr_t rx_dma; unsigned cs_change:1; u8 tx_nbits; u8 rx_nbits; #define SPI_NBITS_SINGLE 0x01 /* 1bit transfer */ #define SPI_NBITS_DUAL 0x02 /* 2bits transfer */ #define SPI_NBITS_QUAD 0x04 /* 4bits transfer */ u8 bits_per_word; u16 delay_usecs; u32 speed_hz; Loading Loading @@ -874,7 +898,7 @@ struct spi_board_info { /* mode becomes spi_device.mode, and is essential for chips * where the default of SPI_CS_HIGH = 0 is wrong. */ u8 mode; u16 mode; /* ... may need additional spi_device chip config data here. * avoid stuff protocol drivers can set; but include stuff Loading