xref: /rk3399_ARM-atf/drivers/mtd/spi-mem/spi_mem.c (revision 05e6a5638b256a66c81d5427e020dbe184659304)
1*05e6a563SLionel Debieve /*
2*05e6a563SLionel Debieve  * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
3*05e6a563SLionel Debieve  *
4*05e6a563SLionel Debieve  * SPDX-License-Identifier: BSD-3-Clause
5*05e6a563SLionel Debieve  */
6*05e6a563SLionel Debieve 
7*05e6a563SLionel Debieve #include <assert.h>
8*05e6a563SLionel Debieve 
9*05e6a563SLionel Debieve #include <libfdt.h>
10*05e6a563SLionel Debieve 
11*05e6a563SLionel Debieve #include <drivers/spi_mem.h>
12*05e6a563SLionel Debieve #include <lib/utils_def.h>
13*05e6a563SLionel Debieve 
14*05e6a563SLionel Debieve #define SPI_MEM_DEFAULT_SPEED_HZ 100000U
15*05e6a563SLionel Debieve 
16*05e6a563SLionel Debieve /*
17*05e6a563SLionel Debieve  * struct spi_slave - Representation of a SPI slave.
18*05e6a563SLionel Debieve  *
19*05e6a563SLionel Debieve  * @max_hz:		Maximum speed for this slave in Hertz.
20*05e6a563SLionel Debieve  * @cs:			ID of the chip select connected to the slave.
21*05e6a563SLionel Debieve  * @mode:		SPI mode to use for this slave (see SPI mode flags).
22*05e6a563SLionel Debieve  * @ops:		Ops defined by the bus.
23*05e6a563SLionel Debieve  */
24*05e6a563SLionel Debieve struct spi_slave {
25*05e6a563SLionel Debieve 	unsigned int max_hz;
26*05e6a563SLionel Debieve 	unsigned int cs;
27*05e6a563SLionel Debieve 	unsigned int mode;
28*05e6a563SLionel Debieve 	const struct spi_bus_ops *ops;
29*05e6a563SLionel Debieve };
30*05e6a563SLionel Debieve 
31*05e6a563SLionel Debieve static struct spi_slave spi_slave;
32*05e6a563SLionel Debieve 
33*05e6a563SLionel Debieve static bool spi_mem_check_buswidth_req(uint8_t buswidth, bool tx)
34*05e6a563SLionel Debieve {
35*05e6a563SLionel Debieve 	switch (buswidth) {
36*05e6a563SLionel Debieve 	case 1U:
37*05e6a563SLionel Debieve 		return true;
38*05e6a563SLionel Debieve 
39*05e6a563SLionel Debieve 	case 2U:
40*05e6a563SLionel Debieve 		if ((tx && (spi_slave.mode & (SPI_TX_DUAL | SPI_TX_QUAD)) !=
41*05e6a563SLionel Debieve 		     0U) ||
42*05e6a563SLionel Debieve 		    (!tx && (spi_slave.mode & (SPI_RX_DUAL | SPI_RX_QUAD)) !=
43*05e6a563SLionel Debieve 		     0U)) {
44*05e6a563SLionel Debieve 			return true;
45*05e6a563SLionel Debieve 		}
46*05e6a563SLionel Debieve 		break;
47*05e6a563SLionel Debieve 
48*05e6a563SLionel Debieve 	case 4U:
49*05e6a563SLionel Debieve 		if ((tx && (spi_slave.mode & SPI_TX_QUAD) != 0U) ||
50*05e6a563SLionel Debieve 		    (!tx && (spi_slave.mode & SPI_RX_QUAD) != 0U)) {
51*05e6a563SLionel Debieve 			return true;
52*05e6a563SLionel Debieve 		}
53*05e6a563SLionel Debieve 		break;
54*05e6a563SLionel Debieve 
55*05e6a563SLionel Debieve 	default:
56*05e6a563SLionel Debieve 		break;
57*05e6a563SLionel Debieve 	}
58*05e6a563SLionel Debieve 
59*05e6a563SLionel Debieve 	return false;
60*05e6a563SLionel Debieve }
61*05e6a563SLionel Debieve 
62*05e6a563SLionel Debieve static bool spi_mem_supports_op(const struct spi_mem_op *op)
63*05e6a563SLionel Debieve {
64*05e6a563SLionel Debieve 	if (!spi_mem_check_buswidth_req(op->cmd.buswidth, true)) {
65*05e6a563SLionel Debieve 		return false;
66*05e6a563SLionel Debieve 	}
67*05e6a563SLionel Debieve 
68*05e6a563SLionel Debieve 	if ((op->addr.nbytes != 0U) &&
69*05e6a563SLionel Debieve 	    !spi_mem_check_buswidth_req(op->addr.buswidth, true)) {
70*05e6a563SLionel Debieve 		return false;
71*05e6a563SLionel Debieve 	}
72*05e6a563SLionel Debieve 
73*05e6a563SLionel Debieve 	if ((op->dummy.nbytes != 0U) &&
74*05e6a563SLionel Debieve 	    !spi_mem_check_buswidth_req(op->dummy.buswidth, true)) {
75*05e6a563SLionel Debieve 		return false;
76*05e6a563SLionel Debieve 	}
77*05e6a563SLionel Debieve 
78*05e6a563SLionel Debieve 	if ((op->data.nbytes != 0U) &&
79*05e6a563SLionel Debieve 	    !spi_mem_check_buswidth_req(op->data.buswidth,
80*05e6a563SLionel Debieve 				       op->data.dir == SPI_MEM_DATA_OUT)) {
81*05e6a563SLionel Debieve 		return false;
82*05e6a563SLionel Debieve 	}
83*05e6a563SLionel Debieve 
84*05e6a563SLionel Debieve 	return true;
85*05e6a563SLionel Debieve }
86*05e6a563SLionel Debieve 
87*05e6a563SLionel Debieve static int spi_mem_set_speed_mode(void)
88*05e6a563SLionel Debieve {
89*05e6a563SLionel Debieve 	const struct spi_bus_ops *ops = spi_slave.ops;
90*05e6a563SLionel Debieve 	int ret;
91*05e6a563SLionel Debieve 
92*05e6a563SLionel Debieve 	ret = ops->set_speed(spi_slave.max_hz);
93*05e6a563SLionel Debieve 	if (ret != 0) {
94*05e6a563SLionel Debieve 		VERBOSE("Cannot set speed (err=%d)\n", ret);
95*05e6a563SLionel Debieve 		return ret;
96*05e6a563SLionel Debieve 	}
97*05e6a563SLionel Debieve 
98*05e6a563SLionel Debieve 	ret = ops->set_mode(spi_slave.mode);
99*05e6a563SLionel Debieve 	if (ret != 0) {
100*05e6a563SLionel Debieve 		VERBOSE("Cannot set mode (err=%d)\n", ret);
101*05e6a563SLionel Debieve 		return ret;
102*05e6a563SLionel Debieve 	}
103*05e6a563SLionel Debieve 
104*05e6a563SLionel Debieve 	return 0;
105*05e6a563SLionel Debieve }
106*05e6a563SLionel Debieve 
107*05e6a563SLionel Debieve static int spi_mem_check_bus_ops(const struct spi_bus_ops *ops)
108*05e6a563SLionel Debieve {
109*05e6a563SLionel Debieve 	bool error = false;
110*05e6a563SLionel Debieve 
111*05e6a563SLionel Debieve 	if (ops->claim_bus == NULL) {
112*05e6a563SLionel Debieve 		VERBOSE("Ops claim bus is not defined\n");
113*05e6a563SLionel Debieve 		error = true;
114*05e6a563SLionel Debieve 	}
115*05e6a563SLionel Debieve 
116*05e6a563SLionel Debieve 	if (ops->release_bus == NULL) {
117*05e6a563SLionel Debieve 		VERBOSE("Ops release bus is not defined\n");
118*05e6a563SLionel Debieve 		error = true;
119*05e6a563SLionel Debieve 	}
120*05e6a563SLionel Debieve 
121*05e6a563SLionel Debieve 	if (ops->exec_op == NULL) {
122*05e6a563SLionel Debieve 		VERBOSE("Ops exec op is not defined\n");
123*05e6a563SLionel Debieve 		error = true;
124*05e6a563SLionel Debieve 	}
125*05e6a563SLionel Debieve 
126*05e6a563SLionel Debieve 	if (ops->set_speed == NULL) {
127*05e6a563SLionel Debieve 		VERBOSE("Ops set speed is not defined\n");
128*05e6a563SLionel Debieve 		error = true;
129*05e6a563SLionel Debieve 	}
130*05e6a563SLionel Debieve 
131*05e6a563SLionel Debieve 	if (ops->set_mode == NULL) {
132*05e6a563SLionel Debieve 		VERBOSE("Ops set mode is not defined\n");
133*05e6a563SLionel Debieve 		error = true;
134*05e6a563SLionel Debieve 	}
135*05e6a563SLionel Debieve 
136*05e6a563SLionel Debieve 	return error ? -EINVAL : 0;
137*05e6a563SLionel Debieve }
138*05e6a563SLionel Debieve 
139*05e6a563SLionel Debieve /*
140*05e6a563SLionel Debieve  * spi_mem_exec_op() - Execute a memory operation.
141*05e6a563SLionel Debieve  * @op: The memory operation to execute.
142*05e6a563SLionel Debieve  *
143*05e6a563SLionel Debieve  * This function first checks that @op is supported and then tries to execute
144*05e6a563SLionel Debieve  * it.
145*05e6a563SLionel Debieve  *
146*05e6a563SLionel Debieve  * Return: 0 in case of success, a negative error code otherwise.
147*05e6a563SLionel Debieve  */
148*05e6a563SLionel Debieve int spi_mem_exec_op(const struct spi_mem_op *op)
149*05e6a563SLionel Debieve {
150*05e6a563SLionel Debieve 	const struct spi_bus_ops *ops = spi_slave.ops;
151*05e6a563SLionel Debieve 	int ret;
152*05e6a563SLionel Debieve 
153*05e6a563SLionel Debieve 	VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addqr:%llx len:%x\n",
154*05e6a563SLionel Debieve 		__func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
155*05e6a563SLionel Debieve 		op->dummy.buswidth, op->data.buswidth,
156*05e6a563SLionel Debieve 		op->addr.val, op->data.nbytes);
157*05e6a563SLionel Debieve 
158*05e6a563SLionel Debieve 	if (!spi_mem_supports_op(op)) {
159*05e6a563SLionel Debieve 		WARN("Error in spi_mem_support\n");
160*05e6a563SLionel Debieve 		return -ENOTSUP;
161*05e6a563SLionel Debieve 	}
162*05e6a563SLionel Debieve 
163*05e6a563SLionel Debieve 	ret = ops->claim_bus(spi_slave.cs);
164*05e6a563SLionel Debieve 	if (ret != 0) {
165*05e6a563SLionel Debieve 		WARN("Error claim_bus\n");
166*05e6a563SLionel Debieve 		return ret;
167*05e6a563SLionel Debieve 	}
168*05e6a563SLionel Debieve 
169*05e6a563SLionel Debieve 	ret = ops->exec_op(op);
170*05e6a563SLionel Debieve 
171*05e6a563SLionel Debieve 	ops->release_bus();
172*05e6a563SLionel Debieve 
173*05e6a563SLionel Debieve 	return ret;
174*05e6a563SLionel Debieve }
175*05e6a563SLionel Debieve 
176*05e6a563SLionel Debieve /*
177*05e6a563SLionel Debieve  * spi_mem_init_slave() - SPI slave device initialization.
178*05e6a563SLionel Debieve  * @fdt: Pointer to the device tree blob.
179*05e6a563SLionel Debieve  * @bus_node: Offset of the bus node.
180*05e6a563SLionel Debieve  * @ops: The SPI bus ops defined.
181*05e6a563SLionel Debieve  *
182*05e6a563SLionel Debieve  * This function first checks that @ops are supported and then tries to find
183*05e6a563SLionel Debieve  * a SPI slave device.
184*05e6a563SLionel Debieve  *
185*05e6a563SLionel Debieve  * Return: 0 in case of success, a negative error code otherwise.
186*05e6a563SLionel Debieve  */
187*05e6a563SLionel Debieve int spi_mem_init_slave(void *fdt, int bus_node, const struct spi_bus_ops *ops)
188*05e6a563SLionel Debieve {
189*05e6a563SLionel Debieve 	int ret;
190*05e6a563SLionel Debieve 	int mode = 0;
191*05e6a563SLionel Debieve 	int nchips = 0;
192*05e6a563SLionel Debieve 	int bus_subnode = 0;
193*05e6a563SLionel Debieve 	const fdt32_t *cuint = NULL;
194*05e6a563SLionel Debieve 
195*05e6a563SLionel Debieve 	ret = spi_mem_check_bus_ops(ops);
196*05e6a563SLionel Debieve 	if (ret != 0) {
197*05e6a563SLionel Debieve 		return ret;
198*05e6a563SLionel Debieve 	}
199*05e6a563SLionel Debieve 
200*05e6a563SLionel Debieve 	fdt_for_each_subnode(bus_subnode, fdt, bus_node) {
201*05e6a563SLionel Debieve 		nchips++;
202*05e6a563SLionel Debieve 	}
203*05e6a563SLionel Debieve 
204*05e6a563SLionel Debieve 	if (nchips != 1) {
205*05e6a563SLionel Debieve 		ERROR("Only one SPI device is currently supported\n");
206*05e6a563SLionel Debieve 		return -EINVAL;
207*05e6a563SLionel Debieve 	}
208*05e6a563SLionel Debieve 
209*05e6a563SLionel Debieve 	fdt_for_each_subnode(bus_subnode, fdt, bus_node) {
210*05e6a563SLionel Debieve 		/* Get chip select */
211*05e6a563SLionel Debieve 		cuint = fdt_getprop(fdt, bus_subnode, "reg", NULL);
212*05e6a563SLionel Debieve 		if (cuint == NULL) {
213*05e6a563SLionel Debieve 			ERROR("Chip select not well defined\n");
214*05e6a563SLionel Debieve 			return -EINVAL;
215*05e6a563SLionel Debieve 		}
216*05e6a563SLionel Debieve 		spi_slave.cs = fdt32_to_cpu(*cuint);
217*05e6a563SLionel Debieve 
218*05e6a563SLionel Debieve 		/* Get max slave frequency */
219*05e6a563SLionel Debieve 		spi_slave.max_hz = SPI_MEM_DEFAULT_SPEED_HZ;
220*05e6a563SLionel Debieve 		cuint = fdt_getprop(fdt, bus_subnode,
221*05e6a563SLionel Debieve 				    "spi-max-frequency", NULL);
222*05e6a563SLionel Debieve 		if (cuint != NULL) {
223*05e6a563SLionel Debieve 			spi_slave.max_hz = fdt32_to_cpu(*cuint);
224*05e6a563SLionel Debieve 		}
225*05e6a563SLionel Debieve 
226*05e6a563SLionel Debieve 		/* Get mode */
227*05e6a563SLionel Debieve 		if ((fdt_getprop(fdt, bus_subnode, "spi-cpol", NULL)) != NULL) {
228*05e6a563SLionel Debieve 			mode |= SPI_CPOL;
229*05e6a563SLionel Debieve 		}
230*05e6a563SLionel Debieve 		if ((fdt_getprop(fdt, bus_subnode, "spi-cpha", NULL)) != NULL) {
231*05e6a563SLionel Debieve 			mode |= SPI_CPHA;
232*05e6a563SLionel Debieve 		}
233*05e6a563SLionel Debieve 		if ((fdt_getprop(fdt, bus_subnode, "spi-cs-high", NULL)) !=
234*05e6a563SLionel Debieve 		    NULL) {
235*05e6a563SLionel Debieve 			mode |= SPI_CS_HIGH;
236*05e6a563SLionel Debieve 		}
237*05e6a563SLionel Debieve 		if ((fdt_getprop(fdt, bus_subnode, "spi-3wire", NULL)) !=
238*05e6a563SLionel Debieve 		    NULL) {
239*05e6a563SLionel Debieve 			mode |= SPI_3WIRE;
240*05e6a563SLionel Debieve 		}
241*05e6a563SLionel Debieve 		if ((fdt_getprop(fdt, bus_subnode, "spi-half-duplex", NULL)) !=
242*05e6a563SLionel Debieve 		    NULL) {
243*05e6a563SLionel Debieve 			mode |= SPI_PREAMBLE;
244*05e6a563SLionel Debieve 		}
245*05e6a563SLionel Debieve 
246*05e6a563SLionel Debieve 		/* Get dual/quad mode */
247*05e6a563SLionel Debieve 		cuint = fdt_getprop(fdt, bus_subnode, "spi-tx-bus-width", NULL);
248*05e6a563SLionel Debieve 		if (cuint != NULL) {
249*05e6a563SLionel Debieve 			switch (fdt32_to_cpu(*cuint)) {
250*05e6a563SLionel Debieve 			case 1U:
251*05e6a563SLionel Debieve 				break;
252*05e6a563SLionel Debieve 			case 2U:
253*05e6a563SLionel Debieve 				mode |= SPI_TX_DUAL;
254*05e6a563SLionel Debieve 				break;
255*05e6a563SLionel Debieve 			case 4U:
256*05e6a563SLionel Debieve 				mode |= SPI_TX_QUAD;
257*05e6a563SLionel Debieve 				break;
258*05e6a563SLionel Debieve 			default:
259*05e6a563SLionel Debieve 				WARN("spi-tx-bus-width %d not supported\n",
260*05e6a563SLionel Debieve 				     fdt32_to_cpu(*cuint));
261*05e6a563SLionel Debieve 				return -EINVAL;
262*05e6a563SLionel Debieve 			}
263*05e6a563SLionel Debieve 		}
264*05e6a563SLionel Debieve 
265*05e6a563SLionel Debieve 		cuint = fdt_getprop(fdt, bus_subnode, "spi-rx-bus-width", NULL);
266*05e6a563SLionel Debieve 		if (cuint != NULL) {
267*05e6a563SLionel Debieve 			switch (fdt32_to_cpu(*cuint)) {
268*05e6a563SLionel Debieve 			case 1U:
269*05e6a563SLionel Debieve 				break;
270*05e6a563SLionel Debieve 			case 2U:
271*05e6a563SLionel Debieve 				mode |= SPI_RX_DUAL;
272*05e6a563SLionel Debieve 				break;
273*05e6a563SLionel Debieve 			case 4U:
274*05e6a563SLionel Debieve 				mode |= SPI_RX_QUAD;
275*05e6a563SLionel Debieve 				break;
276*05e6a563SLionel Debieve 			default:
277*05e6a563SLionel Debieve 				WARN("spi-rx-bus-width %d not supported\n",
278*05e6a563SLionel Debieve 				     fdt32_to_cpu(*cuint));
279*05e6a563SLionel Debieve 				return -EINVAL;
280*05e6a563SLionel Debieve 			}
281*05e6a563SLionel Debieve 		}
282*05e6a563SLionel Debieve 
283*05e6a563SLionel Debieve 		spi_slave.mode = mode;
284*05e6a563SLionel Debieve 		spi_slave.ops = ops;
285*05e6a563SLionel Debieve 	}
286*05e6a563SLionel Debieve 
287*05e6a563SLionel Debieve 	return spi_mem_set_speed_mode();
288*05e6a563SLionel Debieve }
289