1 /** @file
2   This file defines the SPI Configuration Protocol.
3 
4   Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7   @par Revision Reference:
8     This Protocol was introduced in UEFI PI Specification 1.6.
9 
10 **/
11 
12 #ifndef __SPI_CONFIGURATION_PROTOCOL_H__
13 #define __SPI_CONFIGURATION_PROTOCOL_H__
14 
15 ///
16 /// Global ID for the SPI Configuration Protocol
17 ///
18 #define EFI_SPI_CONFIGURATION_GUID  \
19   { 0x85a6d3e6, 0xb65b, 0x4afc,     \
20     { 0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
21 
22 ///
23 /// Macros to easily specify frequencies in hertz, kilohertz and megahertz.
24 ///
25 #define Hz(Frequency)   (Frequency)
26 #define KHz(Frequency)  (1000 * Hz (Frequency))
27 #define MHz(Frequency)  (1000 * KHz (Frequency))
28 
29 typedef struct _EFI_SPI_PERIPHERAL EFI_SPI_PERIPHERAL;
30 
31 /**
32   Manipulate the chip select for a SPI device.
33 
34   This routine must be called at or below TPL_NOTIFY.
35   Update the value of the chip select line for a SPI peripheral.
36   The SPI bus layer calls this routine either in the board layer or in the SPI
37   controller to manipulate the chip select pin at the start and end of a SPI
38   transaction.
39 
40   @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data structure
41                             describing the SPI peripheral whose chip select pin
42                             is to be manipulated. The routine may access the
43                             ChipSelectParameter field to gain sufficient
44                             context to complete the operation.
45   @param[in] PinValue       The value to be applied to the chip select line of
46                             the SPI peripheral.
47 
48   @retval EFI_SUCCESS            The chip select was set successfully
49   @retval EFI_NOT_READY          Support for the chip select is not properly
50                                  initialized
51   @retval EFI_INVALID_PARAMETER  The SpiPeripheral->ChipSelectParameter value
52                                  is invalid
53 
54 **/
55 typedef
56 EFI_STATUS
57 (EFIAPI *EFI_SPI_CHIP_SELECT) (
58   IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
59   IN BOOLEAN                   PinValue
60   );
61 
62 /**
63   Set up the clock generator to produce the correct clock frequency, phase and
64   polarity for a SPI chip.
65 
66   This routine must be called at or below TPL_NOTIFY.
67   This routine updates the clock generator to generate the correct frequency
68   and polarity for the SPI clock.
69 
70   @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data structure from
71                             which the routine can access the ClockParameter,
72                             ClockPhase and ClockPolarity fields. The routine
73                             also has access to the names for the SPI bus and
74                             chip which can be used during debugging.
75   @param[in] ClockHz        Pointer to the requested clock frequency. The clock
76                             generator will choose a supported clock frequency
77                             which is less then or equal to this value.
78                             Specify zero to turn the clock generator off.
79                             The actual clock frequency supported by the clock
80                             generator will be returned.
81 
82   @retval EFI_SUCCESS      The clock was set up successfully
83   @retval EFI_UNSUPPORTED  The SPI controller was not able to support the
84                            frequency requested by CLockHz
85 
86 **/
87 typedef EFI_STATUS
88 (EFIAPI *EFI_SPI_CLOCK) (
89   IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
90   IN UINT32                    *ClockHz
91   );
92 
93 ///
94 /// The EFI_SPI_PART data structure provides a description of a SPI part which
95 /// is independent of the use on the board. This data is available directly
96 /// from the part's datasheet and may be provided by the vendor.
97 ///
98 typedef struct _EFI_SPI_PART {
99   ///
100   /// A Unicode string specifying the SPI chip vendor.
101   ///
102   CONST CHAR16 *Vendor;
103 
104   ///
105   /// A Unicode string specifying the SPI chip part number.
106   ///
107   CONST CHAR16 *PartNumber;
108 
109   ///
110   /// The minimum SPI bus clock frequency used to access this chip. This value
111   /// may be specified in the chip's datasheet. If not, use the value of zero.
112   ///
113   UINT32       MinClockHz;
114 
115   ///
116   /// The maximum SPI bus clock frequency used to access this chip. This value
117   /// is found in the chip's datasheet.
118   ///
119   UINT32       MaxClockHz;
120 
121   ///
122   /// Specify the polarity of the chip select pin. This value can be found in
123   /// the SPI chip's datasheet. Specify TRUE when a one asserts the chip select
124   ///and FALSE when a zero asserts the chip select.
125   ///
126   BOOLEAN      ChipSelectPolarity;
127 } EFI_SPI_PART;
128 
129 ///
130 /// The EFI_SPI_BUS data structure provides the connection details between the
131 /// physical SPI bus and the EFI_SPI_HC_PROTOCOL instance which controls that
132 /// SPI bus. This data structure also describes the details of how the clock is
133 /// generated for that SPI bus. Finally this data structure provides the list
134 /// of physical SPI devices which are attached to the SPI bus.
135 ///
136 typedef struct _EFI_SPI_BUS {
137   ///
138   /// A Unicode string describing the SPI bus
139   ///
140   CONST CHAR16                   *FriendlyName;
141 
142   ///
143   /// Address of the first EFI_SPI_PERIPHERAL data structure connected to this
144   /// bus. Specify NULL if there are no SPI peripherals connected to this bus.
145   ///
146   CONST EFI_SPI_PERIPHERAL       *Peripherallist;
147 
148   ///
149   /// Address of an EFI_DEVICE_PATH_PROTOCOL data structure which uniquely
150   /// describes the SPI controller.
151   ///
152   CONST EFI_DEVICE_PATH_PROTOCOL *ControllerPath;
153 
154   ///
155   /// Address of the routine which controls the clock used by the SPI bus for
156   /// this SPI peripheral. The SPI host co ntroller's clock routine is called
157   /// when this value is set to NULL.
158   ///
159   EFI_SPI_CLOCK                  Clock;
160 
161   ///
162   /// Address of a data structure containing the additional values which
163   /// describe the necessary control for the clock. When Clock is NULL,
164   /// the declaration for this data structure is provided by the vendor of the
165   /// host's SPI controller driver. When Clock is not NULL, the declaration for
166   /// this data structure is provided by the board layer.
167   ///
168   VOID                           *ClockParameter;
169 } EFI_SPI_BUS;
170 
171 ///
172 /// The EFI_SPI_PERIPHERAL data structure describes how a specific block of
173 /// logic which is connected to the SPI bus. This data structure also selects
174 /// which upper level driver is used to manipulate this SPI device.
175 /// The SpiPeripheraLDriverGuid is available from the vendor of the SPI
176 /// peripheral driver.
177 ///
178 struct _EFI_SPI_PERIPHERAL {
179   ///
180   /// Address of the next EFI_SPI_PERIPHERAL data structure. Specify NULL if
181   /// the current data structure is the last one on the SPI bus.
182   ///
183   CONST EFI_SPI_PERIPHERAL *NextSpiPeripheral;
184 
185   ///
186   /// A unicode string describing the function of the SPI part.
187   ///
188   CONST CHAR16             *FriendlyName;
189 
190   ///
191   /// Address of a GUID provided by the vendor of the SPI peripheral driver.
192   /// Instead of using a " EFI_SPI_IO_PROTOCOL" GUID, the SPI bus driver uses
193   /// this GUID to identify an EFI_SPI_IO_PROTOCOL data structure and to
194   /// provide the connection points for the SPI peripheral drivers.
195   /// This reduces the comparison logic in the SPI peripheral driver's
196   /// Supported routine.
197   ///
198   CONST GUID               *SpiPeripheralDriverGuid;
199 
200   ///
201   /// The address of an EFI_SPI_PART data structure which describes this chip.
202   ///
203   CONST EFI_SPI_PART       *SpiPart;
204 
205   ///
206   /// The maximum clock frequency is specified in the EFI_SPI_P ART. When this
207   /// this value is non-zero and less than the value in the EFI_SPI_PART then
208   /// this value is used for the maximum clock frequency for the SPI part.
209   ///
210   UINT32                   MaxClockHz;
211 
212   ///
213   /// Specify the idle value of the clock as found in the datasheet.
214   /// Use zero (0) if the clock'S idle value is low or one (1) if the the
215   /// clock's idle value is high.
216   ///
217   BOOLEAN                  ClockPolarity;
218 
219   ///
220   /// Specify the clock delay after chip select. Specify zero (0) to delay an
221   /// entire clock cycle or one (1) to delay only half a clock cycle.
222   ///
223   BOOLEAN                  ClockPhase;
224 
225   ///
226   /// SPI peripheral attributes, select zero or more of:
227   /// * SPI_PART_SUPPORTS_2_B1T_DATA_BUS_W1DTH - The SPI peripheral is wired to
228   ///   support a 2-bit data bus
229   /// * SPI_PART_SUPPORTS_4_B1T_DATA_BUS_W1DTH - The SPI peripheral is wired to
230   ///   support a 4-bit data bus
231   ///
232   UINT32                   Attributes;
233 
234   ///
235   /// Address of a vendor specific data structure containing additional board
236   /// configuration details related to the SPI chip. The SPI peripheral layer
237   /// uses this data structure when configuring the chip.
238   ///
239   CONST VOID               *ConfigurationData;
240 
241   ///
242   /// The address of an EFI_SPI_BUS data structure which describes the SPI bus
243   /// to which this chip is connected.
244   ///
245   CONST EFI_SPI_BUS        *SpiBus;
246 
247   ///
248   /// Address of the routine which controls the chip select pin for this SPI
249   /// peripheral. Call the SPI host controller's chip select routine when this
250   /// value is set to NULL.
251   ///
252   EFI_SPI_CHIP_SELECT      ChipSelect;
253 
254   ///
255   /// Address of a data structure containing the additional values which
256   /// describe the necessary control for the chip select. When ChipSelect is
257   /// NULL, the declaration for this data structure is provided by the vendor
258   /// of the host's SPI controller driver. The vendor's documentation specifies
259   /// the necessary values to use for the chip select pin selection and
260   /// control. When Chipselect is not NULL, the declaration for this data
261   /// structure is provided by the board layer.
262   ///
263   VOID                     *ChipSelectParameter;
264 };
265 
266 ///
267 /// Describe the details of the board's SPI busses to the SPI driver stack.
268 /// The board layer uses the EFI_SPI_CONFIGURATION_PROTOCOL to expose the data
269 /// tables which describe the board's SPI busses, The SPI bus layer uses these
270 /// tables to configure the clock, chip select and manage the SPI transactions
271 /// on the SPI controllers.
272 ///
273 typedef struct _EFI_SPI_CONFIGURATION_PROTOCOL {
274   ///
275   /// The number of SPI busses on the board.
276   ///
277   UINT32                          BusCount;
278 
279   ///
280   /// The address of an array of EFI_SPI_BUS data structure addresses.
281   ///
282   CONST EFI_SPI_BUS *CONST *CONST Buslist;
283 } EFI_SPI_CONFIGURATION_PROTOCOL;
284 
285 extern EFI_GUID gEfiSpiConfigurationProtocolGuid;
286 
287 #endif // __SPI_CONFIGURATION_PROTOCOL_H__
288