aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/spi/spi.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/spi/spi.h')
-rw-r--r--include/linux/spi/spi.h120
1 files changed, 101 insertions, 19 deletions
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index fbf8c0d95968..cfe42f8cd7a4 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -26,6 +26,7 @@ struct spi_controller;
struct spi_transfer;
struct spi_controller_mem_ops;
struct spi_controller_mem_caps;
+struct spi_message;
/*
* INTERFACES between SPI master-side drivers and SPI slave protocol handlers,
@@ -119,6 +120,8 @@ struct spi_delay {
extern int spi_delay_to_ns(struct spi_delay *_delay, struct spi_transfer *xfer);
extern int spi_delay_exec(struct spi_delay *_delay, struct spi_transfer *xfer);
+extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg,
+ struct spi_transfer *xfer);
/**
* struct spi_device - Controller side proxy for an SPI slave device
@@ -181,8 +184,18 @@ struct spi_device {
u8 chip_select;
u8 bits_per_word;
bool rt;
-#define SPI_NO_TX BIT(31) /* No transmit wire */
-#define SPI_NO_RX BIT(30) /* No receive wire */
+#define SPI_NO_TX BIT(31) /* No transmit wire */
+#define SPI_NO_RX BIT(30) /* No receive wire */
+ /*
+ * TPM specification defines flow control over SPI. Client device
+ * can insert a wait state on MISO when address is transmitted by
+ * controller on MOSI. Detecting the wait state in software is only
+ * possible for full duplex controllers. For controllers that support
+ * only half-duplex, the wait state detection needs to be implemented
+ * in hardware. TPM devices would set this flag when hardware flow
+ * control is expected from SPI controller.
+ */
+#define SPI_TPM_HW_FLOW BIT(29) /* TPM HW flow control */
/*
* All bits defined above should be covered by SPI_MODE_KERNEL_MASK.
* The SPI_MODE_KERNEL_MASK has the SPI_MODE_USER_MASK counterpart,
@@ -192,7 +205,7 @@ struct spi_device {
* These bits must not overlap. A static assert check should make sure of that.
* If adding extra bits, make sure to decrease the bit index below as well.
*/
-#define SPI_MODE_KERNEL_MASK (~(BIT(30) - 1))
+#define SPI_MODE_KERNEL_MASK (~(BIT(29) - 1))
u32 mode;
int irq;
void *controller_state;
@@ -223,7 +236,7 @@ struct spi_device {
static_assert((SPI_MODE_KERNEL_MASK & SPI_MODE_USER_MASK) == 0,
"SPI_MODE_USER_MASK & SPI_MODE_KERNEL_MASK must not overlap");
-static inline struct spi_device *to_spi_device(struct device *dev)
+static inline struct spi_device *to_spi_device(const struct device *dev)
{
return dev ? container_of(dev, struct spi_device, dev) : NULL;
}
@@ -241,7 +254,7 @@ static inline void spi_dev_put(struct spi_device *spi)
}
/* ctldata is for the bus_controller driver's runtime state */
-static inline void *spi_get_ctldata(struct spi_device *spi)
+static inline void *spi_get_ctldata(const struct spi_device *spi)
{
return spi->controller_state;
}
@@ -258,12 +271,30 @@ static inline void spi_set_drvdata(struct spi_device *spi, void *data)
dev_set_drvdata(&spi->dev, data);
}
-static inline void *spi_get_drvdata(struct spi_device *spi)
+static inline void *spi_get_drvdata(const struct spi_device *spi)
{
return dev_get_drvdata(&spi->dev);
}
-struct spi_message;
+static inline u8 spi_get_chipselect(const struct spi_device *spi, u8 idx)
+{
+ return spi->chip_select;
+}
+
+static inline void spi_set_chipselect(struct spi_device *spi, u8 idx, u8 chipselect)
+{
+ spi->chip_select = chipselect;
+}
+
+static inline struct gpio_desc *spi_get_csgpiod(const struct spi_device *spi, u8 idx)
+{
+ return spi->cs_gpiod;
+}
+
+static inline void spi_set_csgpiod(struct spi_device *spi, u8 idx, struct gpio_desc *csgpiod)
+{
+ spi->cs_gpiod = csgpiod;
+}
/**
* struct spi_driver - Host side "protocol" driver
@@ -356,6 +387,7 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
* @max_speed_hz: Highest supported transfer speed
* @flags: other constraints relevant to this driver
* @slave: indicates that this is an SPI slave controller
+ * @target: indicates that this is an SPI target controller
* @devm_allocated: whether the allocation of this struct is devres-managed
* @max_transfer_size: function that returns the max transfer size for
* a &spi_device; may be %NULL, so the default %SIZE_MAX will be used.
@@ -440,6 +472,7 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
* @mem_caps: controller capabilities for the handling of memory operations.
* @unprepare_message: undo any work done by prepare_message().
* @slave_abort: abort the ongoing transfer request on an SPI slave controller
+ * @target_abort: abort the ongoing transfer request on an SPI target controller
* @cs_gpiods: Array of GPIO descs to use as chip select lines; one per CS
* number. Any individual value may be NULL for CS lines that
* are not GPIOs (driven by the SPI controller itself).
@@ -535,8 +568,12 @@ struct spi_controller {
/* Flag indicating if the allocation of this struct is devres-managed */
bool devm_allocated;
- /* Flag indicating this is an SPI slave controller */
- bool slave;
+ union {
+ /* Flag indicating this is an SPI slave controller */
+ bool slave;
+ /* Flag indicating this is an SPI target controller */
+ bool target;
+ };
/*
* on some hardware transfer / message size may be constrained
@@ -649,7 +686,10 @@ struct spi_controller {
struct spi_message *message);
int (*unprepare_message)(struct spi_controller *ctlr,
struct spi_message *message);
- int (*slave_abort)(struct spi_controller *ctlr);
+ union {
+ int (*slave_abort)(struct spi_controller *ctlr);
+ int (*target_abort)(struct spi_controller *ctlr);
+ };
/*
* These hooks are for drivers that use a generic implementation
@@ -727,6 +767,11 @@ static inline bool spi_controller_is_slave(struct spi_controller *ctlr)
return IS_ENABLED(CONFIG_SPI_SLAVE) && ctlr->slave;
}
+static inline bool spi_controller_is_target(struct spi_controller *ctlr)
+{
+ return IS_ENABLED(CONFIG_SPI_SLAVE) && ctlr->target;
+}
+
/* PM calls that need to be issued by the driver */
extern int spi_controller_suspend(struct spi_controller *ctlr);
extern int spi_controller_resume(struct spi_controller *ctlr);
@@ -763,6 +808,21 @@ static inline struct spi_controller *spi_alloc_slave(struct device *host,
return __spi_alloc_controller(host, size, true);
}
+static inline struct spi_controller *spi_alloc_host(struct device *dev,
+ unsigned int size)
+{
+ return __spi_alloc_controller(dev, size, false);
+}
+
+static inline struct spi_controller *spi_alloc_target(struct device *dev,
+ unsigned int size)
+{
+ if (!IS_ENABLED(CONFIG_SPI_SLAVE))
+ return NULL;
+
+ return __spi_alloc_controller(dev, size, true);
+}
+
struct spi_controller *__devm_spi_alloc_controller(struct device *dev,
unsigned int size,
bool slave);
@@ -782,6 +842,21 @@ static inline struct spi_controller *devm_spi_alloc_slave(struct device *dev,
return __devm_spi_alloc_controller(dev, size, true);
}
+static inline struct spi_controller *devm_spi_alloc_host(struct device *dev,
+ unsigned int size)
+{
+ return __devm_spi_alloc_controller(dev, size, false);
+}
+
+static inline struct spi_controller *devm_spi_alloc_target(struct device *dev,
+ unsigned int size)
+{
+ if (!IS_ENABLED(CONFIG_SPI_SLAVE))
+ return NULL;
+
+ return __devm_spi_alloc_controller(dev, size, true);
+}
+
extern int spi_register_controller(struct spi_controller *ctlr);
extern int devm_spi_register_controller(struct device *dev,
struct spi_controller *ctlr);
@@ -957,6 +1032,9 @@ struct spi_transfer {
void *rx_buf;
unsigned len;
+#define SPI_TRANS_FAIL_NO_START BIT(0)
+ u16 error;
+
dma_addr_t tx_dma;
dma_addr_t rx_dma;
struct sg_table tx_sg;
@@ -967,6 +1045,7 @@ struct spi_transfer {
unsigned cs_change:1;
unsigned tx_nbits:3;
unsigned rx_nbits:3;
+ unsigned timestamped:1;
#define SPI_NBITS_SINGLE 0x01 /* 1bit transfer */
#define SPI_NBITS_DUAL 0x02 /* 2bits transfer */
#define SPI_NBITS_QUAD 0x04 /* 4bits transfer */
@@ -983,12 +1062,7 @@ struct spi_transfer {
struct ptp_system_timestamp *ptp_sts;
- bool timestamped;
-
struct list_head transfer_list;
-
-#define SPI_TRANS_FAIL_NO_START BIT(0)
- u16 error;
};
/**
@@ -1029,6 +1103,9 @@ struct spi_message {
unsigned is_dma_mapped:1;
+ /* spi_prepare_message() was called for this message */
+ bool prepared;
+
/* REVISIT: we might want a flag affecting the behavior of the
* last transfer ... allowing things like "read 16 bit length L"
* immediately followed by "read L bytes". Basically imposing
@@ -1041,11 +1118,11 @@ struct spi_message {
*/
/* Completion is reported through a callback */
+ int status;
void (*complete)(void *context);
void *context;
unsigned frame_length;
unsigned actual_length;
- int status;
/* For optional use by whatever driver currently owns the
* spi_message ... between calls to spi_async and then later
@@ -1056,9 +1133,6 @@ struct spi_message {
/* List of spi_res reources when the spi message is processed */
struct list_head resources;
-
- /* spi_prepare_message() was called for this message */
- bool prepared;
};
static inline void spi_message_init_no_memset(struct spi_message *m)
@@ -1141,6 +1215,7 @@ static inline void spi_message_free(struct spi_message *m)
extern int spi_setup(struct spi_device *spi);
extern int spi_async(struct spi_device *spi, struct spi_message *message);
extern int spi_slave_abort(struct spi_device *spi);
+extern int spi_target_abort(struct spi_device *spi);
static inline size_t
spi_max_message_size(struct spi_device *spi)
@@ -1230,6 +1305,10 @@ extern int spi_split_transfers_maxsize(struct spi_controller *ctlr,
struct spi_message *msg,
size_t maxsize,
gfp_t gfp);
+extern int spi_split_transfers_maxwords(struct spi_controller *ctlr,
+ struct spi_message *msg,
+ size_t maxwords,
+ gfp_t gfp);
/*---------------------------------------------------------------------------*/
@@ -1514,6 +1593,9 @@ extern void spi_unregister_device(struct spi_device *spi);
extern const struct spi_device_id *
spi_get_device_id(const struct spi_device *sdev);
+extern const void *
+spi_get_device_match_data(const struct spi_device *sdev);
+
static inline bool
spi_transfer_is_last(struct spi_controller *ctlr, struct spi_transfer *xfer)
{