1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 #include <commonlib/helpers.h>
5 #include <spi-generic.h>
9 int spi_claim_bus(const struct spi_slave
*slave
)
11 const struct spi_ctrlr
*ctrlr
= slave
->ctrlr
;
12 if (ctrlr
&& ctrlr
->claim_bus
)
13 return ctrlr
->claim_bus(slave
);
17 void spi_release_bus(const struct spi_slave
*slave
)
19 const struct spi_ctrlr
*ctrlr
= slave
->ctrlr
;
20 if (ctrlr
&& ctrlr
->release_bus
)
21 ctrlr
->release_bus(slave
);
24 static int spi_xfer_single_op(const struct spi_slave
*slave
,
27 const struct spi_ctrlr
*ctrlr
= slave
->ctrlr
;
30 if (!ctrlr
|| !ctrlr
->xfer
)
33 ret
= ctrlr
->xfer(slave
, op
->dout
, op
->bytesout
, op
->din
, op
->bytesin
);
35 op
->status
= SPI_OP_FAILURE
;
37 op
->status
= SPI_OP_SUCCESS
;
42 static int spi_xfer_vector_default(const struct spi_slave
*slave
,
43 struct spi_op vectors
[], size_t count
)
48 for (i
= 0; i
< count
; i
++) {
49 ret
= spi_xfer_single_op(slave
, &vectors
[i
]);
57 int spi_xfer_vector(const struct spi_slave
*slave
,
58 struct spi_op vectors
[], size_t count
)
60 const struct spi_ctrlr
*ctrlr
= slave
->ctrlr
;
62 if (ctrlr
&& ctrlr
->xfer_vector
)
63 return ctrlr
->xfer_vector(slave
, vectors
, count
);
65 return spi_xfer_vector_default(slave
, vectors
, count
);
68 int spi_xfer(const struct spi_slave
*slave
, const void *dout
, size_t bytesout
,
69 void *din
, size_t bytesin
)
71 const struct spi_ctrlr
*ctrlr
= slave
->ctrlr
;
73 if (ctrlr
&& ctrlr
->xfer
)
74 return ctrlr
->xfer(slave
, dout
, bytesout
, din
, bytesin
);
79 unsigned int spi_crop_chunk(const struct spi_slave
*slave
, unsigned int cmd_len
,
82 const struct spi_ctrlr
*ctrlr
= slave
->ctrlr
;
83 unsigned int ctrlr_max
;
85 bool deduct_opcode_len
;
90 deduct_cmd_len
= !!(ctrlr
->flags
& SPI_CNTRLR_DEDUCT_CMD_LEN
);
91 deduct_opcode_len
= !!(ctrlr
->flags
& SPI_CNTRLR_DEDUCT_OPCODE_LEN
);
92 ctrlr_max
= ctrlr
->max_xfer_size
;
94 assert(ctrlr_max
!= 0);
96 /* Assume opcode is always one byte and deduct it from the cmd_len
97 as the hardware has a separate register for the opcode. */
98 if (deduct_opcode_len
)
101 /* Subtract command length from usable buffer size. If
102 deduct_opcode_len is set, only subtract the number command bytes
103 after the opcode. If the adjusted cmd_len is larger than ctrlr_max
104 return 0 to indicate an error. */
105 if (deduct_cmd_len
) {
106 if (ctrlr_max
>= cmd_len
) {
107 ctrlr_max
-= cmd_len
;
110 printk(BIOS_WARNING
, "%s: Command longer than buffer\n", __func__
);
114 return MIN(ctrlr_max
, buf_len
);
117 void __weak
spi_init(void)
119 /* Default weak implementation - do nothing. */
122 int spi_setup_slave(unsigned int bus
, unsigned int cs
, struct spi_slave
*slave
)
126 memset(slave
, 0, sizeof(*slave
));
128 for (i
= 0; i
< spi_ctrlr_bus_map_count
; i
++) {
129 if ((spi_ctrlr_bus_map
[i
].bus_start
<= bus
) &&
130 (spi_ctrlr_bus_map
[i
].bus_end
>= bus
)) {
131 slave
->ctrlr
= spi_ctrlr_bus_map
[i
].ctrlr
;
136 if (slave
->ctrlr
== NULL
) {
137 printk(BIOS_ERR
, "Can't find SPI bus %u\n", bus
);
144 if (slave
->ctrlr
->setup
)
145 return slave
->ctrlr
->setup(slave
);