Skip to content

Commit 10c1e49

Browse files
Tomasz BursztykaAnas Nashif
authored andcommitted
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 <[email protected]>
1 parent d9007a0 commit 10c1e49

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

drivers/spi/spi_dw.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,11 @@ static int spi_dw_transceive_async(struct spi_config *config,
337337
}
338338
#endif /* CONFIG_POLL */
339339

340+
static int spi_dw_release(struct spi_config *config)
341+
{
342+
return 0;
343+
}
344+
340345
void spi_dw_isr(struct device *dev)
341346
{
342347
const struct spi_dw_config *info = dev->config->config_info;
@@ -373,6 +378,7 @@ static const struct spi_driver_api dw_spi_api = {
373378
#ifdef CONFIG_POLL
374379
.transceive_async = spi_dw_transceive_async,
375380
#endif
381+
.release = spi_dw_release,
376382
};
377383

378384
int spi_dw_init(struct device *dev)

include/spi.h

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,18 @@ extern "C" {
103103

104104
#define SPI_LINES_MASK (0x3 << 11)
105105

106+
/**
107+
* @brief Specific SPI devices control bits
108+
*/
109+
/* Requests - if possible - to keep CS asserted after the transaction */
110+
#define SPI_HOLD_ON_CS BIT(13)
111+
/* Keep the device locked after the transaction for the current config.
112+
* Use this with extreme caution (see spi_release() below) as it will
113+
* prevent other callers to access the SPI device until spi_release() is
114+
* properly called.
115+
*/
116+
#define SPI_LOCK_ON BIT(14)
117+
106118
/**
107119
* @brief SPI Chip Select control structure
108120
*
@@ -132,12 +144,17 @@ struct spi_cs_control {
132144
* transfer [ 4 ] - LSB or MSB first.
133145
* word_size [ 5 : 10 ] - Size of a data frame in bits.
134146
* lines [ 11 : 12 ] - MISO lines: Single/Dual/Quad.
135-
* RESERVED [ 13 : 15 ] - Unused yet
147+
* cs_hold [ 13 ] - Hold on the CS line if possible.
148+
* lock_on [ 14 ] - Keep ressource locked for the caller.
149+
* RESERVED [ 15 ] - Unused yet
136150
*
137151
* slave is the slave number from 0 to host constoller slave limit.
138152
*
139153
* cs is a valid pointer on a struct spi_cs_control is CS line is
140154
* emulated through a gpio line, or NULL otherwise.
155+
*
156+
* Note: cs_hold and lock_on can be changed between consecutive transceive
157+
* call.
141158
*/
142159
struct spi_config {
143160
struct device *dev;
@@ -181,6 +198,14 @@ typedef int (*spi_api_io_async)(struct spi_config *config,
181198
struct spi_buf **rx_bufs,
182199
struct k_poll_signal *async);
183200

201+
/**
202+
* @typedef spi_api_release
203+
* @brief Callback API for unlocking SPI device.
204+
* See spi_release() for argument descriptions
205+
*/
206+
typedef int (*spi_api_release)(struct spi_config *config);
207+
208+
184209
/**
185210
* @brief SPI driver API
186211
* This is the mandatory API any SPI driver needs to expose.
@@ -190,6 +215,7 @@ struct spi_driver_api {
190215
#ifdef CONFIG_POLL
191216
spi_api_io_async transceive_async;
192217
#endif
218+
spi_api_release release;
193219
};
194220

195221
/**
@@ -329,6 +355,25 @@ static inline int spi_write_async(struct spi_config *config,
329355
}
330356
#endif /* CONFIG_POLL */
331357

358+
/**
359+
* @brief Release the SPI device locked on by the current config
360+
*
361+
* Note: This synchronous function is used to release the lock on the SPI
362+
* device that was kept if, and if only, given config parameter was
363+
* the last one to be used (in any of the above functions) and if
364+
* it has the SPI_LOCK_ON bit set into its operation bits field.
365+
* This can be used if the caller needs to keep its hand on the SPI
366+
* device for consecutive transactions.
367+
*
368+
* @param config Pointer to a valid spi_config structure instance.
369+
*/
370+
static inline int spi_release(struct spi_config *config)
371+
{
372+
const struct spi_driver_api *api = config->dev->driver_api;
373+
374+
return api->release(config);
375+
}
376+
332377
#ifdef __cplusplus
333378
}
334379
#endif

0 commit comments

Comments
 (0)