xref: /aosp_15_r20/external/arm-trusted-firmware/include/drivers/spi_mem.h (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  */
6*54fd6939SJiyong Park 
7*54fd6939SJiyong Park #ifndef DRIVERS_SPI_MEM_H
8*54fd6939SJiyong Park #define DRIVERS_SPI_MEM_H
9*54fd6939SJiyong Park 
10*54fd6939SJiyong Park #include <errno.h>
11*54fd6939SJiyong Park #include <stdbool.h>
12*54fd6939SJiyong Park #include <stdint.h>
13*54fd6939SJiyong Park 
14*54fd6939SJiyong Park #define SPI_MEM_BUSWIDTH_1_LINE		1U
15*54fd6939SJiyong Park #define SPI_MEM_BUSWIDTH_2_LINE		2U
16*54fd6939SJiyong Park #define SPI_MEM_BUSWIDTH_4_LINE		4U
17*54fd6939SJiyong Park 
18*54fd6939SJiyong Park /*
19*54fd6939SJiyong Park  * enum spi_mem_data_dir - Describes the direction of a SPI memory data
20*54fd6939SJiyong Park  *			   transfer from the controller perspective.
21*54fd6939SJiyong Park  * @SPI_MEM_DATA_IN: data coming from the SPI memory.
22*54fd6939SJiyong Park  * @SPI_MEM_DATA_OUT: data sent to the SPI memory.
23*54fd6939SJiyong Park  */
24*54fd6939SJiyong Park enum spi_mem_data_dir {
25*54fd6939SJiyong Park 	SPI_MEM_DATA_IN,
26*54fd6939SJiyong Park 	SPI_MEM_DATA_OUT,
27*54fd6939SJiyong Park };
28*54fd6939SJiyong Park 
29*54fd6939SJiyong Park /*
30*54fd6939SJiyong Park  * struct spi_mem_op - Describes a SPI memory operation.
31*54fd6939SJiyong Park  *
32*54fd6939SJiyong Park  * @cmd.buswidth: Number of IO lines used to transmit the command.
33*54fd6939SJiyong Park  * @cmd.opcode: Operation opcode.
34*54fd6939SJiyong Park  * @addr.nbytes: Number of address bytes to send. Can be zero if the operation
35*54fd6939SJiyong Park  *		 does not need to send an address.
36*54fd6939SJiyong Park  * @addr.buswidth: Number of IO lines used to transmit the address.
37*54fd6939SJiyong Park  * @addr.val: Address value. This value is always sent MSB first on the bus.
38*54fd6939SJiyong Park  *	      Note that only @addr.nbytes are taken into account in this
39*54fd6939SJiyong Park  *	      address value, so users should make sure the value fits in the
40*54fd6939SJiyong Park  *	      assigned number of bytes.
41*54fd6939SJiyong Park  * @dummy.nbytes: Number of dummy bytes to send after an opcode or address. Can
42*54fd6939SJiyong Park  *		  be zero if the operation does not require dummy bytes.
43*54fd6939SJiyong Park  * @dummy.buswidth: Number of IO lines used to transmit the dummy bytes.
44*54fd6939SJiyong Park  * @data.buswidth: Number of IO lines used to send/receive the data.
45*54fd6939SJiyong Park  * @data.dir: Direction of the transfer.
46*54fd6939SJiyong Park  * @data.nbytes: Number of data bytes to transfer.
47*54fd6939SJiyong Park  * @data.buf: Input or output data buffer depending on data::dir.
48*54fd6939SJiyong Park  */
49*54fd6939SJiyong Park struct spi_mem_op {
50*54fd6939SJiyong Park 	struct {
51*54fd6939SJiyong Park 		uint8_t buswidth;
52*54fd6939SJiyong Park 		uint8_t opcode;
53*54fd6939SJiyong Park 	} cmd;
54*54fd6939SJiyong Park 
55*54fd6939SJiyong Park 	struct {
56*54fd6939SJiyong Park 		uint8_t nbytes;
57*54fd6939SJiyong Park 		uint8_t buswidth;
58*54fd6939SJiyong Park 		uint64_t val;
59*54fd6939SJiyong Park 	} addr;
60*54fd6939SJiyong Park 
61*54fd6939SJiyong Park 	struct {
62*54fd6939SJiyong Park 		uint8_t nbytes;
63*54fd6939SJiyong Park 		uint8_t buswidth;
64*54fd6939SJiyong Park 	} dummy;
65*54fd6939SJiyong Park 
66*54fd6939SJiyong Park 	struct {
67*54fd6939SJiyong Park 		uint8_t buswidth;
68*54fd6939SJiyong Park 		enum spi_mem_data_dir dir;
69*54fd6939SJiyong Park 		unsigned int nbytes;
70*54fd6939SJiyong Park 		void *buf;
71*54fd6939SJiyong Park 	} data;
72*54fd6939SJiyong Park };
73*54fd6939SJiyong Park 
74*54fd6939SJiyong Park /* SPI mode flags */
75*54fd6939SJiyong Park #define SPI_CPHA	BIT(0)			/* clock phase */
76*54fd6939SJiyong Park #define SPI_CPOL	BIT(1)			/* clock polarity */
77*54fd6939SJiyong Park #define SPI_CS_HIGH	BIT(2)			/* CS active high */
78*54fd6939SJiyong Park #define SPI_LSB_FIRST	BIT(3)			/* per-word bits-on-wire */
79*54fd6939SJiyong Park #define SPI_3WIRE	BIT(4)			/* SI/SO signals shared */
80*54fd6939SJiyong Park #define SPI_PREAMBLE	BIT(5)			/* Skip preamble bytes */
81*54fd6939SJiyong Park #define SPI_TX_DUAL	BIT(6)			/* transmit with 2 wires */
82*54fd6939SJiyong Park #define SPI_TX_QUAD	BIT(7)			/* transmit with 4 wires */
83*54fd6939SJiyong Park #define SPI_RX_DUAL	BIT(8)			/* receive with 2 wires */
84*54fd6939SJiyong Park #define SPI_RX_QUAD	BIT(9)			/* receive with 4 wires */
85*54fd6939SJiyong Park 
86*54fd6939SJiyong Park struct spi_bus_ops {
87*54fd6939SJiyong Park 	/*
88*54fd6939SJiyong Park 	 * Claim the bus and prepare it for communication.
89*54fd6939SJiyong Park 	 *
90*54fd6939SJiyong Park 	 * @cs:	The chip select.
91*54fd6939SJiyong Park 	 * Returns: 0 if the bus was claimed successfully, or a negative value
92*54fd6939SJiyong Park 	 * if it wasn't.
93*54fd6939SJiyong Park 	 */
94*54fd6939SJiyong Park 	int (*claim_bus)(unsigned int cs);
95*54fd6939SJiyong Park 
96*54fd6939SJiyong Park 	/*
97*54fd6939SJiyong Park 	 * Release the SPI bus.
98*54fd6939SJiyong Park 	 */
99*54fd6939SJiyong Park 	void (*release_bus)(void);
100*54fd6939SJiyong Park 
101*54fd6939SJiyong Park 	/*
102*54fd6939SJiyong Park 	 * Set transfer speed.
103*54fd6939SJiyong Park 	 *
104*54fd6939SJiyong Park 	 * @hz:	The transfer speed in Hertz.
105*54fd6939SJiyong Park 	 * Returns: 0 on success, a negative error code otherwise.
106*54fd6939SJiyong Park 	 */
107*54fd6939SJiyong Park 	int (*set_speed)(unsigned int hz);
108*54fd6939SJiyong Park 
109*54fd6939SJiyong Park 	/*
110*54fd6939SJiyong Park 	 * Set the SPI mode/flags.
111*54fd6939SJiyong Park 	 *
112*54fd6939SJiyong Park 	 * @mode: Requested SPI mode (SPI_... flags).
113*54fd6939SJiyong Park 	 * Returns: 0 on success, a negative error code otherwise.
114*54fd6939SJiyong Park 	 */
115*54fd6939SJiyong Park 	int (*set_mode)(unsigned int mode);
116*54fd6939SJiyong Park 
117*54fd6939SJiyong Park 	/*
118*54fd6939SJiyong Park 	 * Execute a SPI memory operation.
119*54fd6939SJiyong Park 	 *
120*54fd6939SJiyong Park 	 * @op:	The memory operation to execute.
121*54fd6939SJiyong Park 	 * Returns: 0 on success, a negative error code otherwise.
122*54fd6939SJiyong Park 	 */
123*54fd6939SJiyong Park 	int (*exec_op)(const struct spi_mem_op *op);
124*54fd6939SJiyong Park };
125*54fd6939SJiyong Park 
126*54fd6939SJiyong Park int spi_mem_exec_op(const struct spi_mem_op *op);
127*54fd6939SJiyong Park int spi_mem_init_slave(void *fdt, int bus_node,
128*54fd6939SJiyong Park 		       const struct spi_bus_ops *ops);
129*54fd6939SJiyong Park 
130*54fd6939SJiyong Park #endif /* DRIVERS_SPI_MEM_H */
131