OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2009 NVIDIA Corporation. |
| 3 * All rights reserved. |
| 4 * |
| 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: |
| 7 * |
| 8 * Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. |
| 10 * |
| 11 * Redistributions in binary form must reproduce the above copyright notice, |
| 12 * this list of conditions and the following disclaimer in the documentation |
| 13 * and/or other materials provided with the distribution. |
| 14 * |
| 15 * Neither the name of the NVIDIA Corporation nor the names of its contributors |
| 16 * may be used to endorse or promote products derived from this software |
| 17 * without specific prior written permission. |
| 18 * |
| 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 29 * POSSIBILITY OF SUCH DAMAGE. |
| 30 * |
| 31 */ |
| 32 |
| 33 #ifndef INCLUDED_nvrm_spi_H |
| 34 #define INCLUDED_nvrm_spi_H |
| 35 |
| 36 |
| 37 #if defined(__cplusplus) |
| 38 extern "C" |
| 39 { |
| 40 #endif |
| 41 |
| 42 #include "nvrm_pinmux.h" |
| 43 #include "nvrm_module.h" |
| 44 #include "nvrm_init.h" |
| 45 |
| 46 #include "nvcommon.h" |
| 47 |
| 48 /** |
| 49 * NvRmSpiHandle is an opaque context to the NvRmSpiRec interface. |
| 50 */ |
| 51 |
| 52 typedef struct NvRmSpiRec *NvRmSpiHandle; |
| 53 |
| 54 /** |
| 55 * Open the handle for the spi/sflash controller. This api initalise the |
| 56 * sflash/spi controller. |
| 57 * The Instance Id for the sflash and spi controller start from 0. |
| 58 * The handle for the spi/sflash is open in master and slave mode based on the |
| 59 * parameter passed. If the spi handle is opened in master mode the the SPICLK |
| 60 * is generated from the spi controller and it acts like a master for all the |
| 61 * transaction. |
| 62 * |
| 63 * If the spi handle is opened in master mode then the controller can be shared |
| 64 * between different chip select client but if the spi handle is created in the |
| 65 * slave mode then it can not be shared by other client and only one client is |
| 66 * allowed to open the spi handle for the slave mode. |
| 67 * |
| 68 * Assert encountered in debug mode if invalid parameter passed. |
| 69 * |
| 70 * @param hRmDevice Handle to the Rm device. |
| 71 * @param IoModule The Rm IO module to set whether this is the |
| 72 * NvOdmIoModule_Sflash or NvOdmIoModule_Slink or NvOdmIoModule_Spi. |
| 73 * @param InstanceId The Instance Id which starts from the 0. |
| 74 * @param IsMasterMode Tells whether the controller will be open in master mode |
| 75 * or the slave mode? |
| 76 * @param phRmSpi Pointer to the sflash/spi handle where the allocated handle |
| 77 * will be stored. |
| 78 * |
| 79 * @retval NvSuccess Indicates the function is successfully completed |
| 80 * @retval NvError_MemoryMappingFail Indicates the address mapping of the |
| 81 * register failed. |
| 82 * @retval NvError_InsufficientMemory Indicates that memory allocation is |
| 83 * failed. |
| 84 * @retval NvError_NotSupported Indicases that the spi is not supported. |
| 85 * @retval NvError_AlreadyAllocated Indicases that the spi handle is already |
| 86 * allocated to the other slave client. |
| 87 */ |
| 88 |
| 89 NvError NvRmSpiOpen( |
| 90 NvRmDeviceHandle hRmDevice, |
| 91 NvU32 IoModule, |
| 92 NvU32 InstanceId, |
| 93 NvBool IsMasterMode, |
| 94 NvRmSpiHandle * phRmSpi ); |
| 95 |
| 96 /** |
| 97 * Deinitialize the spi controller, disable the clock and release the spi |
| 98 * handle. |
| 99 * |
| 100 * @param hRmSpi A handle from NvRmSpiOpen(). If hRmSpi is NULL, this API does |
| 101 * nothing. |
| 102 */ |
| 103 |
| 104 void NvRmSpiClose( |
| 105 NvRmSpiHandle hRmSpi ); |
| 106 |
| 107 /** |
| 108 * Performs an Spi controller read and write simultaneously in master mode. |
| 109 * This apis is only supported if the handle is open in master mode. |
| 110 * |
| 111 * Every Spi transaction is by definition a simultaneous read and write transact
ion, so |
| 112 * there are no separate APIs for read versus write. However, if you only need |
| 113 * to do a read or write, this API allows you to declare that you are not |
| 114 * interested in the read data, or that the write data is not of interest. |
| 115 * If only read is required then client can pass the NULL pointer to the |
| 116 * pWriteBuffer. Zeros will be sent in this case. |
| 117 * Similarly, if client wants to send data only then he can pass the |
| 118 * pReadBuffer as NULL. |
| 119 * If Read and write is required and he wants to first send the command and |
| 120 * then want to read the response, then he need to send both the valid pointer |
| 121 * read and write. In this case the bytesRequested will be the sum of the |
| 122 * send command size and response size. The size of the pReadBuffer and |
| 123 * pWriteBuffer should be equal to the bytes requetsed. |
| 124 * E.g. Client want to send the 4byte command first and the wants to read the |
| 125 * 4 byte response, then he need a 8 byte pWriteBuffer and 8 byte pReadBuffer. |
| 126 * He will fill the first 4 byte of pWriteBuffer with the command which he |
| 127 * wants to send. After calling this api, he needs to ignore the first 4 bytes |
| 128 * and use the next 4 byte as valid response data in the pReadBuffer. |
| 129 * |
| 130 * This is a blocking API. It will returns when all the data has been transferre
d |
| 131 * over the pins of the SOC (the transaction). |
| 132 * |
| 133 * Several Spi transactions may be performed in a single call to this API, but |
| 134 * only if all of the transactions are to the same chip select and have the same |
| 135 * packet size. |
| 136 * |
| 137 * Transaction sizes from 1 to 32 bits are supported. However, all of the |
| 138 * packets are byte-aligned in memory. Like, if packetBitLength is 12 bit |
| 139 * then client needs the 2 byte for the 1 packet. New packets start from the |
| 140 * new bytes e.g. byte0 and byte1 contain the first packet and byte2 and byte3 |
| 141 * will contain the second packets. |
| 142 * |
| 143 * To perform one transaction, the BytesRequested argument should be: |
| 144 * |
| 145 * (PacketSizeInBits + 7)/8 |
| 146 * |
| 147 * To perform n transactions, BytesRequested should be: |
| 148 * |
| 149 * n*((PacketSizeInBits + 7)/8) |
| 150 * |
| 151 * Within a given |
| 152 * transaction with the packet size larger than 8 bits, the bytes are stored in |
| 153 * order of the MSB (most significant byte) first. |
| 154 * The Packet is formed with the first Byte will be in MSB and then next byte |
| 155 * will be in the next MSB towards the LSB. |
| 156 * |
| 157 * For the example, if One packet need to be send and its size is the 20 bit |
| 158 * then it will require the 3 bytes in the pWriteBuffer and arrangement of the |
| 159 * data are as follows: |
| 160 * The packet is 0x000ABCDE (Packet with length of 20 bit). |
| 161 * pWriteBuff[0] = 0x0A |
| 162 * pWriteBuff[1] = 0xBC |
| 163 * pWtriteBuff[2] = 0xDE |
| 164 * |
| 165 * The most significant bit will be transmitted first i.e. bit20 is transmitted |
| 166 * first and bit 0 will be transmitted last. |
| 167 * |
| 168 * If the transmitted packet (command + receive data) is more than 32 like 33 an
d |
| 169 * want to transfer in the single call (CS should be active) then it can be tran
smitted |
| 170 * in following way: |
| 171 * The transfer is command(8 bit)+Dummy(1bit)+Read (24 bit) = 33 bit of transfer
. |
| 172 * - Send 33 bit as 33 byte and each byte have the 1 valid bit, So packet bit le
ngth = 1 and |
| 173 * bytes requested = 33. |
| 174 * NvU8 pSendData[33], pRecData[33]; |
| 175 * pSendData[0] = (Comamnd >>7) & 0x1; |
| 176 * pSendData[1] = (Command >> 6)& 0x1; |
| 177 * :::::::::::::: |
| 178 * pSendData[8] = DummyBit; |
| 179 * pSendData[9] to pSendData[32] = 0; |
| 180 * Call NvRmSpiTransaction(hRmSpi,SpiPinMap,ChipSelect,ClockSpeedInKHz,pRecData,
pSendData, 33,1); |
| 181 * Now You will get the read data from pRecData[9] to pRecData[32] on bit 0 on e
ach byte. |
| 182 * |
| 183 * - The 33 bit transfer can be also done as 11 byte and each byte have the 3 va
lid bits. |
| 184 * This need to rearrange the command in the pSendData in such a way that each b
yte have the |
| 185 * 3 valid bits. |
| 186 * NvU8 pSendData[11], pRecData[11]; |
| 187 * pSendData[0] = (Comamnd >>4) & 0x7; |
| 188 * pSendData[1] = (Command >> 1)& 0x7; |
| 189 * pSendData[2] = (((Command)& 0x3) <<1) | DummyBit; |
| 190 * pSendData[3] to pSendData[10] = 0; |
| 191 * |
| 192 * Call NvRmSpiTransaction(hRmSpi,SpiPinMap,ChipSelect,ClockSpeedInKHz,pRecData,
pSendData, 11,3); |
| 193 * Now You will get the read data from pRecData[4] to pRecData[10] on lower 3 bi
ts on each byte. |
| 194 * |
| 195 * Similarly the 33 bit transfer can also be done as 6 byte and each 2 bytes con
tain the 11 valid bits. |
| 196 * Call NvRmSpiTransaction(hRmSpi,SpiPinMap,ChipSelect,ClockSpeedInKHz,pRecData,
pSendData, 6,11); |
| 197 * |
| 198 * pReadBuffer and pWriteBuffer may be the same pointer, in which case the |
| 199 * write data is destroyed as we read in the read data. Unless they are |
| 200 * identical pointers, however, pReadBuffer and pWriteBuffer must not overlap. |
| 201 * |
| 202 * @param hOdmSpi The Spi handle allocated in a call to NvOdmSpiOpen(). |
| 203 * @param SpiPinMap For SPI master-mode controllers which are being multiplexed
across |
| 204 * multiple pin mux configurations, this specifies which pin mux configur
ation |
| 205 * should be used for the transaction. Must be 0 when the ODM pin mux qu
ery |
| 206 * specifies a non-multiplexed configuration for the controller. |
| 207 * @param ChipSelectId The chip select Id on which device is connected. |
| 208 * @param ClockSpeedInKHz The clock speed in KHz on which device can communicate
. |
| 209 * @param pReadBuffer A pointer to buffer to be filled in with read data. If thi
s |
| 210 * pointer is NULL, the read data will be discarded. |
| 211 * @param pWriteBuffer A pointer to a buffer from which to obtain write data. If
this |
| 212 * pointer is NULL, the write data will be all zeros. |
| 213 * @param BytesRequested The size of pReadBuffer and pWriteBuffer buffers in byt
es. |
| 214 * @param PacketSizeInBits The packet size in bits of each Spi transaction. |
| 215 * |
| 216 */ |
| 217 |
| 218 void NvRmSpiTransaction( |
| 219 NvRmSpiHandle hRmSpi, |
| 220 NvU32 SpiPinMap, |
| 221 NvU32 ChipSelectId, |
| 222 NvU32 ClockSpeedInKHz, |
| 223 NvU8 * pReadBuffer, |
| 224 NvU8 * pWriteBuffer, |
| 225 NvU32 BytesRequested, |
| 226 NvU32 PacketSizeInBits ); |
| 227 |
| 228 /** |
| 229 * Start an Spi controller read and write simultaneously in the slave mode. |
| 230 * This API is only supported for the spi handle which is opened in slave mode. |
| 231 * |
| 232 * This API will assert if opened spi handle is the master type. |
| 233 * |
| 234 * Every Spi transaction is by definition a simultaneous read and write |
| 235 * transaction, so there are no separate APIs for read versus write. |
| 236 * However, if you only need to start a read or write transaction, this API |
| 237 * allows you to declare that you are not interested in the read data, |
| 238 * or that the write data is not of interest. |
| 239 * If only read is required to start then client can pass NV_TRUE to the the |
| 240 * IsReadTransfer and NULL pointer to the pWriteBuffer. The state of the dataout
|
| 241 * will be set by IsIdleDataOutHigh of the structure NvOdmQuerySpiIdleSignalStat
e |
| 242 * in nvodm_query.h. |
| 243 * Similarly, if client wants to send data only then he can pass NV_FALSE to the |
| 244 * IsReadTransfer. |
| 245 * |
| 246 * This is a nonblocking API. This api start the data transfer and returns to th
e |
| 247 * caller without waiting for the data transfer completion. |
| 248 * |
| 249 * Transaction sizes from 1 to 32 bits are supported. However, all of the |
| 250 * packets are byte-aligned in memory. Like, if packetBitLength is 12 bit |
| 251 * then client needs the 2 byte for the 1 packet. New packets start from the |
| 252 * new bytes e.g. byte0 and byte1 contain the first packet and byte2 and byte3 |
| 253 * will contain the second packets. |
| 254 * |
| 255 * To perform one transaction, the BytesRequested argument should be: |
| 256 * |
| 257 * (PacketSizeInBits + 7)/8 |
| 258 * |
| 259 * To perform n transactions, BytesRequested should be: |
| 260 * |
| 261 * n*((PacketSizeInBits + 7)/8) |
| 262 * |
| 263 * Within a given |
| 264 * transaction with the packet size larger than 8 bits, the bytes are stored in |
| 265 * order of the LSB (least significant byte) first. |
| 266 * The Packet is formed with the first Byte will be in LSB and then next byte |
| 267 * will be in the next LSB towards the MSB. |
| 268 * |
| 269 * For the example, if One packet need to be send and its size is the 20 bit |
| 270 * then it will require the 3 bytes in the pWriteBuffer and arrangement of the |
| 271 * data are as follows: |
| 272 * The packet is 0x000ABCDE (Packet with length of 20 bit). |
| 273 * pWriteBuff[0] = 0xDE |
| 274 * pWriteBuff[1] = 0xBC |
| 275 * pWtriteBuff[2] = 0x0A |
| 276 * |
| 277 * The most significant bit will be transmitted first i.e. bit20 is transmitted |
| 278 * first and bit 0 will be transmitted last. |
| 279 * |
| 280 * @see NvRmSpiGetTransactionData |
| 281 * Typical usecase for the CAIF interface. The step for doing the transfer is: |
| 282 * 1. ACPU calls the NvRmSpiStartTransaction() to configure the spi controller |
| 283 * to set in the receive or transmit mode and make ready for the data transfer. |
| 284 * 2. ACPU then send the signal to the CCPU to send the SPICLK (by activating |
| 285 * the SPI_INT) and start the transaction. CCPU get this signal and start sendin
g |
| 286 * SPICLK. |
| 287 * 3. ACPU will call the NvRmSpiGetTransactionData() to get the data/information
|
| 288 * about the transaction. |
| 289 * 4. After completion of the transfer ACPU inactivate the SPI_INT. |
| 290 * |
| 291 * @param hOdmSpi The Spi handle allocated in a call to NvOdmSpiOpen(). |
| 292 * @param ChipSelectId The chip select Id on which device is connected. |
| 293 * @param ClockSpeedInKHz The clock speed in KHz on which device can communicate
. |
| 294 * @param IsReadTransfer It tells that whether the read transfer is required or |
| 295 * not. If it is NV_TRUE then read transfer is required and the read data will b
e |
| 296 * available in the local buffer of the driver. The client will get the received |
| 297 * data after calling the NvRmSpiGetTransactionData(). |
| 298 * @param pWriteBuffer A pointer to a buffer from which to obtain write data. If
this |
| 299 * pointer is NULL, the write data will be all zeros. |
| 300 * @param BytesRequested The size of pReadBuffer and pWriteBuffer buffers in byt
es. |
| 301 * @param PacketSizeInBits The packet size in bits of each Spi transaction. |
| 302 * |
| 303 */ |
| 304 |
| 305 NvError NvRmSpiStartTransaction( |
| 306 NvRmSpiHandle hRmSpi, |
| 307 NvU32 ChipSelectId, |
| 308 NvU32 ClockSpeedInKHz, |
| 309 NvBool IsReadTransfer, |
| 310 NvU8 * pWriteBuffer, |
| 311 NvU32 BytesRequested, |
| 312 NvU32 PacketSizeInBits ); |
| 313 |
| 314 /** |
| 315 * Get the spi transaction status that is started for the slave mode and wait |
| 316 * if required till the transfer completes for a given timeout error. |
| 317 * If read transaction has been started then it will return the receive data to |
| 318 * the client. |
| 319 * |
| 320 * This is a blocking API and wait for the data transfer completion till the |
| 321 * data requested transfer completes or the timeout happen. |
| 322 * |
| 323 * @see NvRmSpiStartTransaction |
| 324 * |
| 325 * @param hOdmSpi The Spi handle allocated in a call to NvOdmSpiOpen(). |
| 326 * @param pReadBuffer A pointer to buffer to be filled in with read data. If thi
s |
| 327 * pointer is NULL, the read data will be discarded. |
| 328 * @param BytesRequested The size of pReadBuffer and pWriteBuffer buffers in byt
es. |
| 329 * @param BytesTransfererd The number of bytes transferred. |
| 330 * @param WaitTimeout The timeout in millisecond to wait for the trsnaction to b
e |
| 331 * completed. |
| 332 * |
| 333 * @retval NvSuccess Indicates that the operation succeeded. |
| 334 * @retval NvError_Timeout Indicates that the timeout happen. |
| 335 * @retval NvError_InvalidState Indicates that the transfer has not been started
. |
| 336 * |
| 337 */ |
| 338 |
| 339 NvError NvRmSpiGetTransactionData( |
| 340 NvRmSpiHandle hRmSpi, |
| 341 NvU8 * pReadBuffer, |
| 342 NvU32 BytesRequested, |
| 343 NvU32 * pBytesTransfererd, |
| 344 NvU32 WaitTimeout ); |
| 345 |
| 346 /** |
| 347 * Set the signal mode for the spi communication for a given chip select. |
| 348 * After calling this API, the further communication happen with the new |
| 349 * configured signal modes. |
| 350 * The default value of the signal mode is taken from nvodm query and this |
| 351 * api will override the signal mode which is read from query. |
| 352 * |
| 353 * @see NvRmSpiStartTransaction |
| 354 * |
| 355 * @param hOdmSpi The Spi handle allocated in a call to NvOdmSpiOpen(). |
| 356 * @param ChipSelectId The chip select Id on which device is connected. |
| 357 * @param SpiSignalMode The nvodm signal modes which need to be set. |
| 358 * |
| 359 */ |
| 360 |
| 361 void NvRmSpiSetSignalMode( |
| 362 NvRmSpiHandle hRmSpi, |
| 363 NvU32 ChipSelectId, |
| 364 NvU32 SpiSignalMode ); |
| 365 |
| 366 #if defined(__cplusplus) |
| 367 } |
| 368 #endif |
| 369 |
| 370 #endif |
OLD | NEW |