Home | History | Annotate | Download | only in core
      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 <errno.h>
     18 #include <heap.h>
     19 #include <string.h>
     20 
     21 #include <cpu.h>
     22 #include <spi.h>
     23 #include <spi_priv.h>
     24 #include <timer.h>
     25 
     26 #define INFO_PRINT(fmt, ...) do { \
     27         osLog(LOG_INFO, "%s " fmt, "[spi]", ##__VA_ARGS__); \
     28     } while (0);
     29 
     30 #define ERROR_PRINT(fmt, ...) do { \
     31         osLog(LOG_ERROR, "%s " fmt, "[spi] ERROR:", ##__VA_ARGS__); \
     32     } while (0);
     33 
     34 struct SpiDeviceState {
     35     struct SpiDevice dev;
     36 
     37     const struct SpiPacket *packets;
     38     size_t n;
     39     size_t currentBuf;
     40     struct SpiMode mode;
     41     uint16_t tid;
     42 
     43     SpiCbkF rxTxCallback;
     44     void *rxTxCookie;
     45 
     46     SpiCbkF finishCallback;
     47     void *finishCookie;
     48 
     49     int err;
     50 };
     51 #define SPI_DEVICE_TO_STATE(p) ((struct SpiDeviceState *)p)
     52 
     53 static void spiMasterNext(struct SpiDeviceState *state);
     54 static void spiMasterStop(struct SpiDeviceState *state);
     55 static void spiMasterDone(struct SpiDeviceState *state, int err);
     56 
     57 static void spiSlaveNext(struct SpiDeviceState *state);
     58 static void spiSlaveIdle(struct SpiDeviceState *state, int err);
     59 static void spiSlaveDone(struct SpiDeviceState *state);
     60 
     61 static int spiMasterStart(struct SpiDeviceState *state,
     62         spi_cs_t cs, const struct SpiMode *mode)
     63 {
     64     struct SpiDevice *dev = &state->dev;
     65 
     66     if (dev->ops->masterStartAsync)
     67         return dev->ops->masterStartAsync(dev, cs, mode);
     68 
     69     if (dev->ops->masterStartSync) {
     70         int err = dev->ops->masterStartSync(dev, cs, mode);
     71         if (err < 0)
     72             return err;
     73     }
     74 
     75     return dev->ops->masterRxTx(dev, state->packets[0].rxBuf,
     76             state->packets[0].txBuf, state->packets[0].size, mode);
     77 }
     78 
     79 void spi_masterStartAsync_done(struct SpiDevice *dev, int err)
     80 {
     81     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
     82     if (err)
     83         spiMasterDone(state, err);
     84     else
     85         spiMasterNext(state);
     86 }
     87 
     88 static void spiDelayCallback(uint32_t timerId, void *data)
     89 {
     90     spiMasterNext((struct SpiDeviceState *)data);
     91 }
     92 
     93 static void spiMasterNext(struct SpiDeviceState *state)
     94 {
     95     struct SpiDevice *dev = &state->dev;
     96 
     97     if (state->currentBuf == state->n) {
     98         spiMasterStop(state);
     99         return;
    100     }
    101 
    102     size_t i = state->currentBuf;
    103     void *rxBuf = state->packets[i].rxBuf;
    104     const void *txBuf = state->packets[i].txBuf;
    105     size_t size = state->packets[i].size;
    106     const struct SpiMode *mode = &state->mode;
    107 
    108     int err = dev->ops->masterRxTx(dev, rxBuf, txBuf, size, mode);
    109     if (err)
    110         spiMasterDone(state, err);
    111 }
    112 
    113 void spiMasterRxTxDone(struct SpiDevice *dev, int err)
    114 {
    115     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    116     if (err) {
    117         spiMasterDone(state, err);
    118     } else {
    119         size_t i = state->currentBuf++;
    120 
    121         if (state->packets[i].delay > 0) {
    122             if (!timTimerSet(state->packets[i].delay, 0, 50, spiDelayCallback, state, true)) {
    123                 ERROR_PRINT("Cannot do delayed spi, timer depleted\n");
    124                 spiMasterDone(state, -ENOMEM); // should be out of timer; out of mem is close enough
    125             }
    126         } else {
    127             spiMasterNext(state);
    128         }
    129     }
    130 }
    131 
    132 static void spiMasterStop(struct SpiDeviceState *state)
    133 {
    134     struct SpiDevice *dev = &state->dev;
    135 
    136     if (dev->ops->masterStopSync) {
    137         int err = dev->ops->masterStopSync(dev);
    138         spiMasterDone(state, err);
    139     } else if (dev->ops->masterStopAsync) {
    140         int err = dev->ops->masterStopAsync(dev);
    141         if (err < 0)
    142             spiMasterDone(state, err);
    143     } else {
    144         spiMasterDone(state, 0);
    145     }
    146 }
    147 
    148 void spiMasterStopAsyncDone(struct SpiDevice *dev, int err)
    149 {
    150     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    151     spiMasterDone(state, err);
    152 }
    153 
    154 static void spiMasterDone(struct SpiDeviceState *state, int err)
    155 {
    156     SpiCbkF callback = state->rxTxCallback;
    157     void *cookie = state->rxTxCookie;
    158 
    159     uint16_t oldTid = osSetCurrentTid(state->tid);
    160     callback(cookie, err);
    161     osSetCurrentTid(oldTid);
    162 }
    163 
    164 static int spiSlaveStart(struct SpiDeviceState *state,
    165         const struct SpiMode *mode)
    166 {
    167     struct SpiDevice *dev = &state->dev;
    168 
    169     if (dev->ops->slaveStartAsync)
    170         return dev->ops->slaveStartAsync(dev, mode);
    171 
    172     if (dev->ops->slaveStartSync) {
    173         int err = dev->ops->slaveStartSync(dev, mode);
    174         if (err < 0)
    175             return err;
    176     }
    177 
    178     return dev->ops->slaveIdle(dev, mode);
    179 }
    180 
    181 void spiSlaveStartAsyncDone(struct SpiDevice *dev, int err)
    182 {
    183     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    184 
    185     if (err)
    186         state->err = err;
    187     else
    188         state->err = dev->ops->slaveIdle(dev, &state->mode);
    189 }
    190 
    191 void spiSlaveRxTxDone(struct SpiDevice *dev, int err)
    192 {
    193     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    194 
    195     if (err) {
    196         spiSlaveIdle(state, err);
    197     } else {
    198         state->currentBuf++;
    199         spiSlaveNext(state);
    200     }
    201 }
    202 
    203 void spiSlaveCsInactive(struct SpiDevice *dev)
    204 {
    205     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    206 
    207     dev->ops->slaveSetCsInterrupt(dev, false);
    208 
    209     if (!state->finishCallback) {
    210         osLog(LOG_WARN, "%s called without callback\n", __func__);
    211         return;
    212     }
    213 
    214     SpiCbkF callback = state->finishCallback;
    215     void *cookie = state->finishCookie;
    216     state->finishCallback = NULL;
    217     state->finishCookie = NULL;
    218 
    219     uint16_t oldTid = osSetCurrentTid(state->tid);
    220     callback(cookie, 0);
    221     osSetCurrentTid(oldTid);
    222 }
    223 
    224 static void spiSlaveNext(struct SpiDeviceState *state)
    225 {
    226     struct SpiDevice *dev = &state->dev;
    227 
    228     if (state->currentBuf == state->n) {
    229         spiSlaveIdle(state, 0);
    230         return;
    231     }
    232 
    233     size_t i = state->currentBuf;
    234     void *rxBuf = state->packets[i].rxBuf;
    235     const void *txBuf = state->packets[i].txBuf;
    236     size_t size = state->packets[i].size;
    237     const struct SpiMode *mode = &state->mode;
    238 
    239     int err = dev->ops->slaveRxTx(dev, rxBuf, txBuf, size, mode);
    240     if (err)
    241         spiSlaveIdle(state, err);
    242 }
    243 
    244 static void spiSlaveIdle(struct SpiDeviceState *state, int err)
    245 {
    246     struct SpiDevice *dev = &state->dev;
    247     SpiCbkF callback = state->rxTxCallback;
    248     void *cookie = state->rxTxCookie;
    249 
    250     if (!err)
    251         err = dev->ops->slaveIdle(dev, &state->mode);
    252 
    253     uint16_t oldTid = osSetCurrentTid(state->tid);
    254     callback(cookie, err);
    255     osSetCurrentTid(oldTid);
    256 }
    257 
    258 void spiSlaveStopAsyncDone(struct SpiDevice *dev, int err)
    259 {
    260     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    261     spiSlaveDone(state);
    262 }
    263 
    264 static void spiSlaveDone(struct SpiDeviceState *state)
    265 {
    266     struct SpiDevice *dev = &state->dev;
    267 
    268     if (dev->ops->release)
    269         dev->ops->release(dev);
    270     heapFree(state);
    271 }
    272 
    273 static int spiSetupRxTx(struct SpiDeviceState *state,
    274         const struct SpiPacket packets[], size_t n,
    275         SpiCbkF callback, void *cookie)
    276 {
    277     state->packets = packets;
    278     state->n = n;
    279     state->currentBuf = 0;
    280     state->rxTxCallback = callback;
    281     state->rxTxCookie = cookie;
    282     state->tid = osGetCurrentTid();
    283 
    284     return 0;
    285 }
    286 
    287 int spiMasterRequest(uint8_t busId, struct SpiDevice **dev_out)
    288 {
    289     int ret = 0;
    290 
    291     struct SpiDeviceState *state = heapAlloc(sizeof(*state));
    292     if (!state)
    293         return -ENOMEM;
    294     struct SpiDevice *dev = &state->dev;
    295 
    296     ret = spiRequest(dev, busId);
    297     if (ret < 0)
    298         goto err_request;
    299 
    300     if (!dev->ops->masterRxTx) {
    301         ret = -EOPNOTSUPP;
    302         goto err_opsupp;
    303     }
    304 
    305     *dev_out = dev;
    306     return 0;
    307 
    308 err_opsupp:
    309     if (dev->ops->release)
    310         dev->ops->release(dev);
    311 err_request:
    312     heapFree(state);
    313     return ret;
    314 }
    315 
    316 int spiMasterRxTx(struct SpiDevice *dev, spi_cs_t cs,
    317         const struct SpiPacket packets[], size_t n,
    318         const struct SpiMode *mode, SpiCbkF callback,
    319         void *cookie)
    320 {
    321     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    322     int ret = 0;
    323 
    324     if (!n)
    325         return -EINVAL;
    326 
    327     ret = spiSetupRxTx(state, packets, n, callback, cookie);
    328     if (ret < 0)
    329         return ret;
    330 
    331     state->mode = *mode;
    332 
    333     return spiMasterStart(state, cs, mode);
    334 }
    335 
    336 int spiMasterRelease(struct SpiDevice *dev)
    337 {
    338     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    339 
    340     if (dev->ops->release) {
    341         int ret = dev->ops->release(dev);
    342         if (ret < 0)
    343             return ret;
    344     }
    345 
    346     heapFree(state);
    347     return 0;
    348 }
    349 
    350 int spiSlaveRequest(uint8_t busId, const struct SpiMode *mode,
    351         struct SpiDevice **dev_out)
    352 {
    353     int ret = 0;
    354 
    355     struct SpiDeviceState *state = heapAlloc(sizeof(*state));
    356     if (!state)
    357         return -ENOMEM;
    358     struct SpiDevice *dev = &state->dev;
    359 
    360     ret = spiRequest(dev, busId);
    361     if (ret < 0)
    362         goto err_request;
    363 
    364     if (!dev->ops->slaveIdle || !dev->ops->slaveRxTx) {
    365         ret = -EOPNOTSUPP;
    366         goto err_opsupp;
    367     }
    368 
    369     state->mode = *mode;
    370     state->err = 0;
    371 
    372     ret = spiSlaveStart(state, mode);
    373     if (ret < 0)
    374         goto err_opsupp;
    375 
    376     *dev_out = dev;
    377     return 0;
    378 
    379 err_opsupp:
    380     if (dev->ops->release)
    381         dev->ops->release(dev);
    382 err_request:
    383     heapFree(state);
    384     return ret;
    385 }
    386 
    387 int spiSlaveRxTx(struct SpiDevice *dev,
    388         const struct SpiPacket packets[], size_t n,
    389         SpiCbkF callback, void *cookie)
    390 {
    391     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    392 
    393     if (!n)
    394         return -EINVAL;
    395 
    396     if (state->err)
    397         return state->err;
    398 
    399     int ret = spiSetupRxTx(state, packets, n, callback, cookie);
    400     if (ret < 0)
    401         return ret;
    402 
    403     return dev->ops->slaveRxTx(dev, state->packets[0].rxBuf,
    404             state->packets[0].txBuf, state->packets[0].size, &state->mode);
    405 }
    406 
    407 int spiSlaveWaitForInactive(struct SpiDevice *dev, SpiCbkF callback,
    408         void *cookie)
    409 {
    410     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    411 
    412     if (!dev->ops->slaveSetCsInterrupt || !dev->ops->slaveCsIsActive)
    413         return -EOPNOTSUPP;
    414 
    415     state->finishCallback = callback;
    416     state->finishCookie = cookie;
    417 
    418     uint64_t flags = cpuIntsOff();
    419     dev->ops->slaveSetCsInterrupt(dev, true);
    420 
    421     /* CS may already be inactive before enabling the interrupt.  In this case
    422      * roll back and fire the callback immediately.
    423      *
    424      * Interrupts must be off while checking for this.  Otherwise there is a
    425      * (very unlikely) race where the CS interrupt fires between calling
    426      * slaveSetCsInterrupt(true) and the rollback
    427      * slaveSetCsInterrupt(false), causing the event to be handled twice.
    428      *
    429      * Likewise the check must come after enabling the interrupt.  Otherwise
    430      * there is an (also unlikely) race where CS goes inactive between reading
    431      * CS and enabling the interrupt, causing the event to be lost.
    432      */
    433 
    434     bool cs = dev->ops->slaveCsIsActive(dev);
    435     if (!cs) {
    436         dev->ops->slaveSetCsInterrupt(dev, false);
    437         cpuIntsRestore(flags);
    438 
    439         state->finishCallback = NULL;
    440         state->finishCookie = NULL;
    441         callback(cookie, 0);
    442         return 0;
    443     }
    444 
    445     cpuIntsRestore(flags);
    446     return 0;
    447 }
    448 
    449 int spiSlaveRelease(struct SpiDevice *dev)
    450 {
    451     struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
    452     int ret;
    453 
    454     if (dev->ops->slaveStopSync) {
    455         ret = dev->ops->slaveStopSync(dev);
    456         if (ret < 0)
    457             return ret;
    458     } else if (dev->ops->slaveStopAsync) {
    459         return dev->ops->slaveStopAsync(dev);
    460     }
    461 
    462     spiSlaveDone(state);
    463     return 0;
    464 }
    465