Merge remote-tracking branch 'spi/topic/quad' into spi-qspi
This commit is contained in:
commit
21e34a3306
|
@ -885,6 +885,51 @@ static void of_register_spi_devices(struct spi_master *master)
|
||||||
if (of_find_property(nc, "spi-3wire", NULL))
|
if (of_find_property(nc, "spi-3wire", NULL))
|
||||||
spi->mode |= SPI_3WIRE;
|
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 */
|
/* Device speed */
|
||||||
prop = of_get_property(nc, "spi-max-frequency", &len);
|
prop = of_get_property(nc, "spi-max-frequency", &len);
|
||||||
if (!prop || len < sizeof(*prop)) {
|
if (!prop || len < sizeof(*prop)) {
|
||||||
|
@ -1332,6 +1377,19 @@ int spi_setup(struct spi_device *spi)
|
||||||
unsigned bad_bits;
|
unsigned bad_bits;
|
||||||
int status = 0;
|
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
|
/* help drivers fail *cleanly* when they need options
|
||||||
* that aren't supported with their current master
|
* that aren't supported with their current master
|
||||||
*/
|
*/
|
||||||
|
@ -1367,6 +1425,11 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
|
||||||
struct spi_master *master = spi->master;
|
struct spi_master *master = spi->master;
|
||||||
struct spi_transfer *xfer;
|
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
|
/* Half-duplex links include original MicroWire, and ones with
|
||||||
* only one data pin like SPI_3WIRE (switches direction) or where
|
* only one data pin like SPI_3WIRE (switches direction) or where
|
||||||
* either MOSI or MISO is missing. They can also be caused by
|
* either MOSI or MISO is missing. They can also be caused by
|
||||||
|
@ -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
|
* Set transfer bits_per_word and max speed as spi device default if
|
||||||
* it is not set for this transfer.
|
* 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) {
|
list_for_each_entry(xfer, &message->transfers, transfer_list) {
|
||||||
if (!xfer->bits_per_word)
|
if (!xfer->bits_per_word)
|
||||||
xfer->bits_per_word = spi->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;
|
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) {
|
if (master->bits_per_word_mask) {
|
||||||
/* Only 32 bits fit in the mask */
|
/* Only 32 bits fit in the mask */
|
||||||
if (xfer->bits_per_word > 32)
|
if (xfer->bits_per_word > 32)
|
||||||
|
@ -1403,6 +1473,53 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
|
||||||
BIT(xfer->bits_per_word - 1)))
|
BIT(xfer->bits_per_word - 1)))
|
||||||
return -EINVAL;
|
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;
|
message->spi = spi;
|
||||||
|
|
|
@ -74,7 +74,7 @@ struct spi_device {
|
||||||
struct spi_master *master;
|
struct spi_master *master;
|
||||||
u32 max_speed_hz;
|
u32 max_speed_hz;
|
||||||
u8 chip_select;
|
u8 chip_select;
|
||||||
u8 mode;
|
u16 mode;
|
||||||
#define SPI_CPHA 0x01 /* clock phase */
|
#define SPI_CPHA 0x01 /* clock phase */
|
||||||
#define SPI_CPOL 0x02 /* clock polarity */
|
#define SPI_CPOL 0x02 /* clock polarity */
|
||||||
#define SPI_MODE_0 (0|0) /* (original MicroWire) */
|
#define SPI_MODE_0 (0|0) /* (original MicroWire) */
|
||||||
|
@ -87,6 +87,10 @@ struct spi_device {
|
||||||
#define SPI_LOOP 0x20 /* loopback mode */
|
#define SPI_LOOP 0x20 /* loopback mode */
|
||||||
#define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */
|
#define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */
|
||||||
#define SPI_READY 0x80 /* slave pulls low to pause */
|
#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;
|
u8 bits_per_word;
|
||||||
int irq;
|
int irq;
|
||||||
void *controller_state;
|
void *controller_state;
|
||||||
|
@ -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
|
* suported. If set, the SPI core will reject any transfer with an
|
||||||
* unsupported bits_per_word. If not set, this value is simply ignored,
|
* unsupported bits_per_word. If not set, this value is simply ignored,
|
||||||
* and it's up to the individual driver to perform any validation.
|
* 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
|
* @flags: other constraints relevant to this driver
|
||||||
* @bus_lock_spinlock: spinlock for SPI bus locking
|
* @bus_lock_spinlock: spinlock for SPI bus locking
|
||||||
* @bus_lock_mutex: mutex for SPI bus locking
|
* @bus_lock_mutex: mutex for SPI bus locking
|
||||||
|
@ -315,6 +321,10 @@ struct spi_master {
|
||||||
#define SPI_BIT_MASK(bits) (((bits) == 32) ? ~0UL : (BIT(bits) - 1))
|
#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))
|
#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 */
|
/* other constraints relevant to this driver */
|
||||||
u16 flags;
|
u16 flags;
|
||||||
#define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */
|
#define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */
|
||||||
|
@ -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
|
* @rx_buf: data to be read (dma-safe memory), or NULL
|
||||||
* @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped
|
* @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
|
* @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)
|
* @len: size of rx and tx buffers (in bytes)
|
||||||
* @speed_hz: Select a speed other than the device default for this
|
* @speed_hz: Select a speed other than the device default for this
|
||||||
* transfer. If 0 the default (from @spi_device) is used.
|
* transfer. If 0 the default (from @spi_device) is used.
|
||||||
|
@ -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
|
* by the results of previous messages and where the whole transaction
|
||||||
* ends when the chipselect goes intactive.
|
* 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)
|
* The code that submits an spi_message (and its spi_transfers)
|
||||||
* to the lower layers is responsible for managing its memory.
|
* to the lower layers is responsible for managing its memory.
|
||||||
* Zero-initialize every field you don't set up explicitly, to
|
* Zero-initialize every field you don't set up explicitly, to
|
||||||
|
@ -527,6 +546,11 @@ struct spi_transfer {
|
||||||
dma_addr_t rx_dma;
|
dma_addr_t rx_dma;
|
||||||
|
|
||||||
unsigned cs_change:1;
|
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;
|
u8 bits_per_word;
|
||||||
u16 delay_usecs;
|
u16 delay_usecs;
|
||||||
u32 speed_hz;
|
u32 speed_hz;
|
||||||
|
@ -874,7 +898,7 @@ struct spi_board_info {
|
||||||
/* mode becomes spi_device.mode, and is essential for chips
|
/* mode becomes spi_device.mode, and is essential for chips
|
||||||
* where the default of SPI_CS_HIGH = 0 is wrong.
|
* where the default of SPI_CS_HIGH = 0 is wrong.
|
||||||
*/
|
*/
|
||||||
u8 mode;
|
u16 mode;
|
||||||
|
|
||||||
/* ... may need additional spi_device chip config data here.
|
/* ... may need additional spi_device chip config data here.
|
||||||
* avoid stuff protocol drivers can set; but include stuff
|
* avoid stuff protocol drivers can set; but include stuff
|
||||||
|
|
Loading…
Reference in New Issue