| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <hostIntf.h> |
| #include <hostIntf_priv.h> |
| #include <nanohubPacket.h> |
| #include <spi.h> |
| |
| static uint8_t gBusId; |
| static struct SpiDevice *gSpi; |
| |
| static void *gRxBuf; |
| static size_t gTxSize; |
| |
| static struct SpiPacket gPacket; |
| |
| static const struct SpiMode gSpiMode = { |
| .cpol = SPI_CPOL_IDLE_LO, |
| .cpha = SPI_CPHA_LEADING_EDGE, |
| .bitsPerWord = 8, |
| .format = SPI_FORMAT_MSB_FIRST, |
| .txWord = NANOHUB_PREAMBLE_BYTE, |
| }; |
| |
| static void hostIntfSpiRxCallback(void *cookie, int err) |
| { |
| struct NanohubPacket *packet = gRxBuf; |
| HostIntfCommCallbackF callback = cookie; |
| callback(NANOHUB_PACKET_SIZE(packet->len), err); |
| } |
| |
| static void hostIntfSpiTxCallback(void *cookie, int err) |
| { |
| HostIntfCommCallbackF callback = cookie; |
| callback(gTxSize, err); |
| } |
| |
| static int hostIntfSpiRequest() |
| { |
| return spiSlaveRequest(gBusId, &gSpiMode, &gSpi); |
| } |
| |
| static int hostIntfSpiRxPacket(void *rxBuf, size_t rxSize, |
| HostIntfCommCallbackF callback) |
| { |
| int err; |
| |
| gPacket.rxBuf = gRxBuf = rxBuf; |
| gPacket.txBuf = NULL; |
| gPacket.size = rxSize; |
| |
| err = spiSlaveRxTx(gSpi, &gPacket, 1, hostIntfSpiRxCallback, callback); |
| if (err < 0) |
| callback(0, err); |
| |
| return 0; |
| } |
| |
| static int hostIntfSpiTxPacket(const void *txBuf, size_t txSize, |
| HostIntfCommCallbackF callback) |
| { |
| ((uint8_t *)txBuf)[txSize] = NANOHUB_PREAMBLE_BYTE; |
| gTxSize = txSize; |
| |
| gPacket.rxBuf = NULL; |
| gPacket.txBuf = txBuf; |
| gPacket.size = txSize + 1; |
| |
| return spiSlaveRxTx(gSpi, &gPacket, 1, hostIntfSpiTxCallback, |
| callback); |
| } |
| |
| static int hostIntfSpiRelease(void) |
| { |
| return spiSlaveRelease(gSpi); |
| } |
| |
| static const struct HostIntfComm gSpiComm = { |
| .request = hostIntfSpiRequest, |
| .rxPacket = hostIntfSpiRxPacket, |
| .txPacket = hostIntfSpiTxPacket, |
| .release = hostIntfSpiRelease, |
| }; |
| |
| const struct HostIntfComm *hostIntfSpiInit(uint8_t busId) |
| { |
| gBusId = busId; |
| return &gSpiComm; |
| } |