1 /* 2 * Copyright (C) 2016 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 #include <hostIntf.h> 18 #include <hostIntf_priv.h> 19 #include <nanohubPacket.h> 20 #include <spi.h> 21 22 static uint8_t gBusId; 23 static struct SpiDevice *gSpi; 24 25 static void *gRxBuf; 26 static size_t gTxSize; 27 28 static struct SpiPacket gPacket; 29 30 static const struct SpiMode gSpiMode = { 31 .cpol = SPI_CPOL_IDLE_LO, 32 .cpha = SPI_CPHA_LEADING_EDGE, 33 .bitsPerWord = 8, 34 .format = SPI_FORMAT_MSB_FIRST, 35 .txWord = NANOHUB_PREAMBLE_BYTE, 36 }; 37 38 static void hostIntfSpiRxCallback(void *cookie, int err) 39 { 40 struct NanohubPacket *packet = gRxBuf; 41 HostIntfCommCallbackF callback = cookie; 42 callback(NANOHUB_PACKET_SIZE(packet->len), err); 43 } 44 45 static void hostIntfSpiTxCallback(void *cookie, int err) 46 { 47 HostIntfCommCallbackF callback = cookie; 48 callback(gTxSize, err); 49 } 50 51 static int hostIntfSpiRequest() 52 { 53 return spiSlaveRequest(gBusId, &gSpiMode, &gSpi); 54 } 55 56 static int hostIntfSpiRxPacket(void *rxBuf, size_t rxSize, 57 HostIntfCommCallbackF callback) 58 { 59 int err; 60 61 gPacket.rxBuf = gRxBuf = rxBuf; 62 gPacket.txBuf = NULL; 63 gPacket.size = rxSize; 64 65 err = spiSlaveRxTx(gSpi, &gPacket, 1, hostIntfSpiRxCallback, callback); 66 if (err < 0) 67 callback(0, err); 68 69 return 0; 70 } 71 72 static int hostIntfSpiTxPacket(const void *txBuf, size_t txSize, 73 HostIntfCommCallbackF callback) 74 { 75 ((uint8_t *)txBuf)[txSize] = NANOHUB_PREAMBLE_BYTE; 76 gTxSize = txSize; 77 78 gPacket.rxBuf = NULL; 79 gPacket.txBuf = txBuf; 80 gPacket.size = txSize + 1; 81 82 return spiSlaveRxTx(gSpi, &gPacket, 1, hostIntfSpiTxCallback, 83 callback); 84 } 85 86 static int hostIntfSpiRelease(void) 87 { 88 return spiSlaveRelease(gSpi); 89 } 90 91 static const struct HostIntfComm gSpiComm = { 92 .request = hostIntfSpiRequest, 93 .rxPacket = hostIntfSpiRxPacket, 94 .txPacket = hostIntfSpiTxPacket, 95 .release = hostIntfSpiRelease, 96 }; 97 98 const struct HostIntfComm *hostIntfSpiInit(uint8_t busId) 99 { 100 gBusId = busId; 101 return &gSpiComm; 102 } 103