1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#pragma once
14
15#include <platsupport/io.h>
16#include <platsupport/clock.h>
17#include <platsupport/gpio.h>
18
19typedef struct spi_bus spi_bus_t;
20typedef struct spi_slave_config spi_slave_config_t;
21
22struct spi_slave_config {
23    int id;
24    /// Device operation speed
25    freq_t   speed_hz;
26    /// Slave selection signal delay in microseconds
27    uint32_t nss_udelay;
28    /// Feedback/propagation delay in clock phases
29    uint32_t fb_delay;
30};
31
32enum spi_cs_state {
33    SPI_CS_ASSERT,
34    SPI_CS_RELAX
35};
36
37/**
38 * Function pointer to override chip select function.
39 *
40 * It is sometimes necessary to override the chip select functionality such
41 * as when GPIO pins are used for chipselect.  This function pointer is passed
42 * in when a SPI driver is initialised.  If NULL is passed then the driver's
43 * default chip select behavior will occur.
44 * @param  config  A pointer to the slave struct
45 * @param  state   The release or assert cs state
46 */
47typedef void (*spi_chipselect_fn)(const spi_slave_config_t* cfg, int state);
48
49#include <platsupport/plat/spi.h>
50
51typedef void (*spi_callback_fn)(spi_bus_t* spi_bus, int status, void* token);
52
53/**
54 * Initialise an SPI bus
55 * @param[in]  id      The id of the SPI bus to initialise
56 * @param[in]  io_ops  A structure providing operations which this device
57 *                     may perform for intialisation.
58 * @param[out] spi_bus A handle to the spi bus driver for future calls
59 * @return             0 on success
60 */
61int spi_init(enum spi_id id, ps_io_ops_t* io_ops, spi_bus_t** spi_bus);
62
63/**
64 * Set the speed of the SPI bus
65 * @param[in] spi_bus  A handle to an SPI bus
66 * @param[in] bps      The speed to set in bits per second.
67 * @return             The actual speed set
68 */
69long spi_set_speed(spi_bus_t* spi_bus, long bps);
70
71/**
72 * Allow the driver to handle an incoming IRQ
73 * @param[in] dev The SPI bus that triggered the IRQ
74 */
75void spi_handle_irq(spi_bus_t* dev);
76
77/**
78 * Configure the SPI bus to meet the slave device's requirement
79 * @param[in] spi_bus  A handle to an SPI bus
80 * @param[in] cfg      Slave configuration
81 */
82void spi_prepare_transfer(spi_bus_t* spi_bus, const spi_slave_config_t* cfg);
83
84/**
85 * Write and read data to and from the SPI bus.
86 * txdata will be sent from byte position 0 until txcnt bytes have been sent.
87 * rxdata will be read once txcnt bytes have been sent and until rxcnt bytes have
88 * been read.
89 * @param[in] spi_bus  A handle to an SPI bus
90 * @param[in] txdata   A reference to the data to be transmitted
91 * @param[in] txcnt    The number of bytes to transmit
92 * @param[in] rxdata   A reference to the location where data should be read into.
93 *                     The buffer should be large enough to store TX echo data as
94 *                     well as the data to be received. ie, if txcnt is 2, then
95 *                     rxdata[0:1] will contain data returned by the TX cycle and
96 *                     rxdata[2:] will contain the received data.
97 * @param[in] rxcnt    The number of bytes to receive. This count only begins after
98 *                     the required amount of data has been transmitted.
99 * @param[in] cb       A callback function to call when all data has been read.
100 *                     If the provided callback function is NULL, the call will block
101 *                     until the transfer is complete
102 * @param[in] token    A token to pass, unmodified, to the callback function.
103 */
104int spi_xfer(spi_bus_t* spi_bus, const void* txdata, size_t txcnt,
105             void* rxdata, size_t rxcnt, spi_callback_fn cb, void* token);
106
107