summaryrefslogtreecommitdiff
path: root/include/spi.h
blob: 28fc166f730020b2b3d036e5330514766f52297e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* Copyright 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* SPI interface for Chrome EC */

#ifndef __CROS_EC_SPI_H
#define __CROS_EC_SPI_H

#include "host_command.h"

/*
 * SPI Clock polarity and phase mode (0 - 3)
 * @code
 * clk mode | POL PHA
 * ---------+--------
 *   0      |  0   0
 *   1      |  0   1
 *   2      |  1   0
 *   3      |  1   1
 * ---------+--------
 * @endcode
 */
enum spi_clock_mode {
	SPI_CLOCK_MODE0 = 0,
	SPI_CLOCK_MODE1 = 1,
	SPI_CLOCK_MODE2 = 2,
	SPI_CLOCK_MODE3 = 3
};

struct spi_device_t {
	/*
	 * SPI port the device is connected to.
	 * On some architecture, this is SPI controller port index,
	 * on other the SPI port index directly.
	 */
	uint8_t port;

	/*
	 * Clock divisor to talk to SPI device.
	 * If several devices share the same port, we select the lowest speed.
	 */
	uint8_t div;

	/* gpio used for chip selection. */
	enum gpio_signal gpio_cs;
};

extern
#ifndef CONFIG_FINGERPRINT_MCU
	const
#endif
	struct spi_device_t spi_devices[];
extern const unsigned int spi_devices_used;

/*
 * The first port in spi_devices defines the port to access the SPI flash.
 * The first gpio defines the CS GPIO to access the flash,
 * if used.
 */
#define SPI_FLASH_DEVICE (&spi_devices[0])

/*
 * Enable / disable the SPI port.  When the port is disabled, all its I/O lines
 * are high-Z so the EC won't interfere with other devices on the SPI bus.
 *
 * @param spi_device device
 * @param enable  1 to enable the SPI device's port, 0 to disable it.
 */
int spi_enable(const struct spi_device_t *spi_device, int enable);

#define SPI_READBACK_ALL (-1)

/*
 * Issue a SPI transaction.  Assumes SPI port has already been enabled.
 *
 * Transmits <txlen> bytes from <txdata>, throwing away the corresponding
 * received data, then transmits <rxlen> bytes, saving the received data
 * in <rxdata>.
 * If SPI_READBACK_ALL is set in <rxlen>, the received data during transmission
 * is recorded in rxdata buffer and it assumes that the real <rxlen> is equal
 * to <txlen>.
 *
 * @param spi_device  the SPI device to use
 * @param txdata  buffer to transmit
 * @param txlen  number of bytes in txdata.
 * @param rxdata  receive buffer.
 * @param rxlen  number of bytes in rxdata or SPI_READBACK_ALL.
 */
int spi_transaction(const struct spi_device_t *spi_device,
		    const uint8_t *txdata, int txlen,
		    uint8_t *rxdata, int rxlen);

/*
 * Similar to spi_transaction(), but hands over to DMA for reading response.
 * Must call spi_transaction_flush() after this to make sure the response is
 * received.
 * Contrary the regular spi_transaction(), this function does NOT lock the
 * SPI port, it's up to the caller to ensure proper mutual exclusion if needed.
 */
int spi_transaction_async(const struct spi_device_t *spi_device,
			  const uint8_t *txdata, int txlen,
			  uint8_t *rxdata, int rxlen);

/* Wait for async response received */
int spi_transaction_flush(const struct spi_device_t *spi_device);

/* Wait for async response received but do not de-assert chip select */
int spi_transaction_wait(const struct spi_device_t *spi_device);

/*
 * Get SPI protocol information. This function is called in runtime if board's
 * host command transport is SPI.
 */
enum ec_status spi_get_protocol_info(struct host_cmd_handler_args *args);

#ifdef CONFIG_SPI
/**
 * Called when the NSS level changes, signalling the start or end of a SPI
 * transaction.
 *
 * @param signal	GPIO signal that changed
 */
void spi_event(enum gpio_signal signal);

#else
static inline void spi_event(enum gpio_signal signal)
{
}

#endif

#endif  /* __CROS_EC_SPI_H */