aboutsummaryrefslogtreecommitdiff
path: root/include/drivers/spi_mem.h
blob: d1953acf4c3c7b0da7bdc555a1220bcf93d3ec74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef DRIVERS_SPI_MEM_H
#define DRIVERS_SPI_MEM_H

#include <errno.h>
#include <stdbool.h>
#include <stdint.h>

#define SPI_MEM_BUSWIDTH_1_LINE		1U
#define SPI_MEM_BUSWIDTH_2_LINE		2U
#define SPI_MEM_BUSWIDTH_4_LINE		4U

/*
 * enum spi_mem_data_dir - Describes the direction of a SPI memory data
 *			   transfer from the controller perspective.
 * @SPI_MEM_DATA_IN: data coming from the SPI memory.
 * @SPI_MEM_DATA_OUT: data sent to the SPI memory.
 */
enum spi_mem_data_dir {
	SPI_MEM_DATA_IN,
	SPI_MEM_DATA_OUT,
};

/*
 * struct spi_mem_op - Describes a SPI memory operation.
 *
 * @cmd.buswidth: Number of IO lines used to transmit the command.
 * @cmd.opcode: Operation opcode.
 * @addr.nbytes: Number of address bytes to send. Can be zero if the operation
 *		 does not need to send an address.
 * @addr.buswidth: Number of IO lines used to transmit the address.
 * @addr.val: Address value. This value is always sent MSB first on the bus.
 *	      Note that only @addr.nbytes are taken into account in this
 *	      address value, so users should make sure the value fits in the
 *	      assigned number of bytes.
 * @dummy.nbytes: Number of dummy bytes to send after an opcode or address. Can
 *		  be zero if the operation does not require dummy bytes.
 * @dummy.buswidth: Number of IO lines used to transmit the dummy bytes.
 * @data.buswidth: Number of IO lines used to send/receive the data.
 * @data.dir: Direction of the transfer.
 * @data.nbytes: Number of data bytes to transfer.
 * @data.buf: Input or output data buffer depending on data::dir.
 */
struct spi_mem_op {
	struct {
		uint8_t buswidth;
		uint8_t opcode;
	} cmd;

	struct {
		uint8_t nbytes;
		uint8_t buswidth;
		uint64_t val;
	} addr;

	struct {
		uint8_t nbytes;
		uint8_t buswidth;
	} dummy;

	struct {
		uint8_t buswidth;
		enum spi_mem_data_dir dir;
		unsigned int nbytes;
		void *buf;
	} data;
};

/* SPI mode flags */
#define SPI_CPHA	BIT(0)			/* clock phase */
#define SPI_CPOL	BIT(1)			/* clock polarity */
#define SPI_CS_HIGH	BIT(2)			/* CS active high */
#define SPI_LSB_FIRST	BIT(3)			/* per-word bits-on-wire */
#define SPI_3WIRE	BIT(4)			/* SI/SO signals shared */
#define SPI_PREAMBLE	BIT(5)			/* Skip preamble bytes */
#define SPI_TX_DUAL	BIT(6)			/* transmit with 2 wires */
#define SPI_TX_QUAD	BIT(7)			/* transmit with 4 wires */
#define SPI_RX_DUAL	BIT(8)			/* receive with 2 wires */
#define SPI_RX_QUAD	BIT(9)			/* receive with 4 wires */

struct spi_bus_ops {
	/*
	 * Claim the bus and prepare it for communication.
	 *
	 * @cs:	The chip select.
	 * Returns: 0 if the bus was claimed successfully, or a negative value
	 * if it wasn't.
	 */
	int (*claim_bus)(unsigned int cs);

	/*
	 * Release the SPI bus.
	 */
	void (*release_bus)(void);

	/*
	 * Set transfer speed.
	 *
	 * @hz:	The transfer speed in Hertz.
	 * Returns: 0 on success, a negative error code otherwise.
	 */
	int (*set_speed)(unsigned int hz);

	/*
	 * Set the SPI mode/flags.
	 *
	 * @mode: Requested SPI mode (SPI_... flags).
	 * Returns: 0 on success, a negative error code otherwise.
	 */
	int (*set_mode)(unsigned int mode);

	/*
	 * Execute a SPI memory operation.
	 *
	 * @op:	The memory operation to execute.
	 * Returns: 0 on success, a negative error code otherwise.
	 */
	int (*exec_op)(const struct spi_mem_op *op);
};

int spi_mem_exec_op(const struct spi_mem_op *op);
int spi_mem_init_slave(void *fdt, int bus_node,
		       const struct spi_bus_ops *ops);

#endif /* DRIVERS_SPI_MEM_H */