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