/* hw/spi.h - Generic SPI definitions * * Copyright (C) 2024 Luke T. Shumaker * SPDX-Licence-Identifier: AGPL-3.0-or-later */ #ifndef _HW_SPI_H_ #define _HW_SPI_H_ #include /* for size_t */ enum spi_mode { SPI_MODE_0 = 0, /* clk_polarity=0 (idle low), clk_phase=0 (sample on rise) */ SPI_MODE_1 = 1, /* clk_polarity=0 (idle low), clk_phase=1 (sample on fall) */ SPI_MODE_2 = 2, /* clk_polarity=1 (idle high), clk_phase=0 (sample on rise) */ SPI_MODE_3 = 3, /* clk_polarity=1 (idle high), clk_phase=1 (sample on fall) */ }; struct bidi_iovec { void *iov_read_dst; void *iov_write_src; size_t iov_len; }; struct spi; /* This API assumes that an SPI frame is a multiple of 8-bits. * * It is my understanding that this is a common constraint of SPI * hardware, and that the RP2040 is somewhat unusual in that it allows * frames of any length 4-16 bits (we disconnect the CS pin from the * PL022 SSP and manually GPIO it from the CPU in order to achieve * longer frames). * * But, more relevantly: The W5500's protocol uses frames that are 4-N * octets; so we have no need for an API that allows a * non-multiple-of-8 number of bits. */ struct spi_vtable { void (*readwritev)(struct spi *, const struct bidi_iovec *iov, int iovcnt); }; struct spi { struct spi_vtable *vtable; /* This is where your implementation data goes. */ char data[0]; }; #endif /* _HW_SPI_H_ */