1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <interface/spi/spi.h> 20 #include <lib/spi/common/utils.h> 21 #include <lk/compiler.h> 22 #include <stdbool.h> 23 #include <stddef.h> 24 #include <stdint.h> 25 #include <trusty_ipc.h> 26 27 __BEGIN_CDECLS 28 29 /** 30 * struct spi_dev - SPI device tracking structure 31 * @h: SPI server connection handle 32 * @shm: state of memory region shared with SPI server 33 * @max_num_cmds: maximum number of commands in one batch 34 * @num_cmds: number of commands in the current batch 35 * @max_total_payload: maximum total number of bytes of payload in one batch 36 * @total_payload: total number of bytes of payload in the current batch 37 * @config_err: whether an error occurred during command configuration 38 * 39 * All members of this structure should be considered private 40 */ 41 struct spi_dev { 42 handle_t h; 43 struct mem_buf shm; 44 size_t max_num_cmds; 45 size_t num_cmds; 46 size_t max_total_payload; 47 size_t total_payload; 48 bool config_err; 49 }; 50 51 /** 52 * spi_dev_open() - open specified SPI device 53 * @dev: pointer to &struct spi_dev 54 * @name: name of device to open 55 * @max_num_cmds: maximum number of commands in one batch 56 * @max_total_payload: maximum total payload size 57 * 58 * Open connection to specified device service, configure command batch limits 59 * and establish a shared memory region with SPI server 60 * 61 * Return: 0 on success, negative error code on error 62 */ 63 int spi_dev_open(struct spi_dev* dev, 64 const char* name, 65 size_t max_num_cmds, 66 size_t max_total_payload); 67 /** 68 * TODO: We don't have a way to return dynamically allocated shared memory yet. 69 * spi_dev_close() - close connection to specified SPI service 70 * @dev: SPI device to close. It should be previously opened with 71 * spi_dev_open() call. 72 * 73 * void spi_dev_close(struct spi_dev* dev); 74 */ 75 76 /** 77 * spi_clear_cmds() - clear SPI commands previously configured for a device 78 * @dev: handle of SPI device previously opened with spi_dev_open() 79 */ 80 void spi_clear_cmds(struct spi_dev* dev); 81 82 /** 83 * spi_exec_cmds() - execute series of SPI commands 84 * @dev: handle of SPI device previously opened with spi_dev_open() 85 * @failed: points to location to store index of failed command if an error 86 * occurred. 87 * 88 * This routine implicitly clears all SPI commands. See spi_clear_cmds(). 89 * If an error occurs, @failed param is set the index of failed command. If 90 * @failed is equal to the number of commands in the sent batch, that means that 91 * the batch was successfully deserialized by SPI server, but failed to commit. 92 * 93 * Return: 0 if all command were successful, negative error code otherwise 94 */ 95 int spi_exec_cmds(struct spi_dev* dev, size_t* failed); 96 97 /** 98 * spi_add_data_xfer_cmd() - configure SPI data command 99 * @dev: handle of SPI device previously opened with spi_dev_open() 100 * @tx: return pointer for data to send 101 * @rx: return pointer for buffer to store received data 102 * @len: number of bytes to send/receive 103 * 104 * This routine configures command to exchange data with specified device. 105 * 106 * CS must be asserted for data transfer to succeed. 107 * 108 * Either @tx or @rx may be NULL to indicate that send-only or receive-only 109 * operation is required. If both @tx and @rx are NULL, then @len bytes of data 110 * is still allocated in shared memory, but not used. Both @tx and @rx may point 111 * to the same memory location. 112 * 113 * @len also controls the number of clock cycles sent the SPI bus. If the 114 * word-size is a multiple of 8 bits, the number of SPI clock cycles are 115 * round_up(@len * 8, word-size). Otherwise, details TBD. 116 * 117 * If this routine fails, all subsequent calls to spi_exec_cmds() and 118 * spi_add_*() routines will fail until spi_clear_cmds() is called. 119 * 120 * Return: 0 on success, negative error code otherwise. 121 */ 122 int spi_add_data_xfer_cmd(struct spi_dev* dev, 123 void** tx, 124 void** rx, 125 size_t len); 126 127 /** 128 * spi_add_cs_assert_cmd() - configure SPI chip select assert command 129 * @dev: handle of SPI device previously opened with spi_dev_open() 130 * 131 * This routine builds a command to assert chip select with 132 * specified device. 133 * 134 * If this routine fails, all subsequent calls to spi_exec_cmds() and 135 * spi_add_*() routines will fail until spi_clear_cmds() is called. 136 * 137 * Return: 0 on success, negative error code otherwise. 138 */ 139 int spi_add_cs_assert_cmd(struct spi_dev* dev); 140 141 /** 142 * spi_add_cs_deassert_cmd() - configure SPI chip select deassert command 143 * @dev: handle of SPI device previously opened with spi_dev_open() 144 * 145 * This routine builds a command to deassert chip select with 146 * specified device. 147 * 148 * If this routine fails, all subsequent calls to spi_exec_cmds() and 149 * spi_add_*() routines will fail until spi_clear_cmds() is called. 150 * 151 * Return: 0 on success, negative error code otherwise. 152 */ 153 int spi_add_cs_deassert_cmd(struct spi_dev* dev); 154 155 /** 156 * spi_add_set_clk_cmd() - configure SPI set clock speed command 157 * @dev: handle of SPI device previously opened with spi_dev_open() 158 * @clk_hz_in: requested SPI clock speed, in Hz 159 * @clk_hz_out: output pointer to actual SPI clock speed that was set, in Hz. 160 * Value is set after spi_exec_cmds() returns. Clients can pass 161 * %NULL if they don't need to know the actual clock rate used. 162 * Actual clock rate must be @clk_hz_in or less. 163 * 164 * This routine builds a command to set clock speed for specified device. 165 * 166 * If this routine fails, all subsequent calls to spi_exec_cmds() and 167 * spi_add_*() routines will fail until spi_clear_cmds() is called. 168 * 169 * Return: 0 on success, or negative error code otherwise. 170 */ 171 int spi_add_set_clk_cmd(struct spi_dev* dev, 172 uint64_t clk_hz_in, 173 uint64_t** clk_hz_out); 174 175 /** 176 * spi_add_set_delay_cmd() - configure SPI delay command 177 * @dev: handle of SPI device previously opened with spi_dev_open() 178 * @delay_ns: amount of time to delay remaining SPI requests by, in ns 179 * 180 * This routine builds a command to delay remaining SPI requests for specified 181 * device. 182 * 183 * There is no way to guarantee exact delays due to scheduling constraints. 184 * Execution of this command is done on a best-effort basis. Actual delay time 185 * must be larger than @delay_ns. If a SPI sequence fails due to unsatisfied 186 * timing requirements, clients may retry. 187 * 188 * If this routine fails, all subsequent calls to spi_exec_cmds() and 189 * spi_add_*() routines will fail until spi_clear_cmds() is called. 190 * 191 * Return: 0 on success, or negative error code otherwise. 192 */ 193 int spi_add_delay_cmd(struct spi_dev* dev, uint64_t delay_ns); 194 195 __END_CDECLS 196