api/spi: Add 2 specific control bits for special use cases.

SPI_HOLD_ON_CS can be used to ask the SPI device to keep CS on, after
the transaction. And this undefinitely, until another config is used.
This will inhibate the gpio cs delay, if any. This might be useful when
doing consecutive calls on one slave without releasing the CS.

SPI_LOCK_ON is to be used with caution as it will keep the SPI device
locked for the current config being used after each transaction. This
can be necessary if one needs to do consecutive calls on a slave without
any olher caller to interfere.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2017-05-10 08:40:00 +02:00 committed by Anas Nashif
commit 10c1e49f84
2 changed files with 52 additions and 1 deletions

View file

@ -337,6 +337,11 @@ static int spi_dw_transceive_async(struct spi_config *config,
}
#endif /* CONFIG_POLL */
static int spi_dw_release(struct spi_config *config)
{
return 0;
}
void spi_dw_isr(struct device *dev)
{
const struct spi_dw_config *info = dev->config->config_info;
@ -373,6 +378,7 @@ static const struct spi_driver_api dw_spi_api = {
#ifdef CONFIG_POLL
.transceive_async = spi_dw_transceive_async,
#endif
.release = spi_dw_release,
};
int spi_dw_init(struct device *dev)

View file

@ -103,6 +103,18 @@ extern "C" {
#define SPI_LINES_MASK (0x3 << 11)
/**
* @brief Specific SPI devices control bits
*/
/* Requests - if possible - to keep CS asserted after the transaction */
#define SPI_HOLD_ON_CS BIT(13)
/* Keep the device locked after the transaction for the current config.
* Use this with extreme caution (see spi_release() below) as it will
* prevent other callers to access the SPI device until spi_release() is
* properly called.
*/
#define SPI_LOCK_ON BIT(14)
/**
* @brief SPI Chip Select control structure
*
@ -132,12 +144,17 @@ struct spi_cs_control {
* transfer [ 4 ] - LSB or MSB first.
* word_size [ 5 : 10 ] - Size of a data frame in bits.
* lines [ 11 : 12 ] - MISO lines: Single/Dual/Quad.
* RESERVED [ 13 : 15 ] - Unused yet
* cs_hold [ 13 ] - Hold on the CS line if possible.
* lock_on [ 14 ] - Keep ressource locked for the caller.
* RESERVED [ 15 ] - Unused yet
*
* slave is the slave number from 0 to host constoller slave limit.
*
* cs is a valid pointer on a struct spi_cs_control is CS line is
* emulated through a gpio line, or NULL otherwise.
*
* Note: cs_hold and lock_on can be changed between consecutive transceive
* call.
*/
struct spi_config {
struct device *dev;
@ -181,6 +198,14 @@ typedef int (*spi_api_io_async)(struct spi_config *config,
struct spi_buf **rx_bufs,
struct k_poll_signal *async);
/**
* @typedef spi_api_release
* @brief Callback API for unlocking SPI device.
* See spi_release() for argument descriptions
*/
typedef int (*spi_api_release)(struct spi_config *config);
/**
* @brief SPI driver API
* This is the mandatory API any SPI driver needs to expose.
@ -190,6 +215,7 @@ struct spi_driver_api {
#ifdef CONFIG_POLL
spi_api_io_async transceive_async;
#endif
spi_api_release release;
};
/**
@ -329,6 +355,25 @@ static inline int spi_write_async(struct spi_config *config,
}
#endif /* CONFIG_POLL */
/**
* @brief Release the SPI device locked on by the current config
*
* Note: This synchronous function is used to release the lock on the SPI
* device that was kept if, and if only, given config parameter was
* the last one to be used (in any of the above functions) and if
* it has the SPI_LOCK_ON bit set into its operation bits field.
* This can be used if the caller needs to keep its hand on the SPI
* device for consecutive transactions.
*
* @param config Pointer to a valid spi_config structure instance.
*/
static inline int spi_release(struct spi_config *config)
{
const struct spi_driver_api *api = config->dev->driver_api;
return api->release(config);
}
#ifdef __cplusplus
}
#endif