xref: /aosp_15_r20/external/coreboot/src/drivers/spi/spiconsole.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <spi-generic.h>
4 #include <spi_flash.h>
5 #include <console/spi.h>
6 
7 static struct spi_slave slave;
8 
spiconsole_init(void)9 void spiconsole_init(void) {
10 	spi_init();
11 	spi_setup_slave(0, 0, &slave);
12 }
13 
14 /*
15  * The EM100 'hyper terminal' specification defines a header of 9 characters.
16  * Because of this, devices with a spi_crop_chunk of less than 10 characters
17  * can't be supported by this standard.
18  *
19  * To add support in romstage, the static struct here and the ones used by
20  * spi_xfer will need to be modified - removed, or mapped into cbmem.
21  *
22  * Because the Dediprog software expects strings, not single characters, and
23  * because of the header overhead, this builds up a buffer to send.
24  */
spiconsole_tx_byte(unsigned char c)25 void spiconsole_tx_byte(unsigned char c) {
26 	static struct em100_msg msg = {
27 		.header.spi_command = EM100_DEDICATED_CMD,
28 		.header.em100_command = EM100_UFIFO_CMD,
29 		.header.msg_signature = EM100_MSG_SIGNATURE,
30 		.header.msg_type = EM100_MSG_ASCII,
31 		.header.msg_length = 0
32 	};
33 
34 	/* Verify the spi buffer is big enough to send even a single byte */
35 	if (spi_crop_chunk(&slave, 0, MAX_MSG_LENGTH) <
36 			sizeof(struct em100_msg_header) + 1)
37 		return;
38 
39 	msg.data[msg.header.msg_length] = c;
40 	msg.header.msg_length++;
41 
42 	/* Send the data on newline or when the max spi length is reached */
43 	if (c == '\n' || (sizeof(struct em100_msg_header) +
44 			msg.header.msg_length == spi_crop_chunk(&slave, 0,
45 			MAX_MSG_LENGTH))) {
46 		spi_xfer(&slave, &msg, sizeof(struct em100_msg_header) +
47 				msg.header.msg_length, NULL, 0);
48 
49 		msg.header.msg_length = 0;
50 	}
51 }
52