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
spiMasterStart(struct SpiDeviceState * state,spi_cs_t cs,const struct SpiMode * mode)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
spi_masterStartAsync_done(struct SpiDevice * dev,int err)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
spiDelayCallback(uint32_t timerId,void * data)88 static void spiDelayCallback(uint32_t timerId, void *data)
89 {
90 spiMasterNext((struct SpiDeviceState *)data);
91 }
92
spiMasterNext(struct SpiDeviceState * state)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
spiMasterRxTxDone(struct SpiDevice * dev,int err)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
spiMasterStop(struct SpiDeviceState * state)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
spiMasterStopAsyncDone(struct SpiDevice * dev,int err)148 void spiMasterStopAsyncDone(struct SpiDevice *dev, int err)
149 {
150 struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
151 spiMasterDone(state, err);
152 }
153
spiMasterDone(struct SpiDeviceState * state,int err)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
spiSlaveStart(struct SpiDeviceState * state,const struct SpiMode * mode)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
spiSlaveStartAsyncDone(struct SpiDevice * dev,int err)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
spiSlaveRxTxDone(struct SpiDevice * dev,int err)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
spiSlaveCsInactive(struct SpiDevice * dev)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
spiSlaveNext(struct SpiDeviceState * state)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
spiSlaveIdle(struct SpiDeviceState * state,int err)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
spiSlaveStopAsyncDone(struct SpiDevice * dev,int err)258 void spiSlaveStopAsyncDone(struct SpiDevice *dev, int err)
259 {
260 struct SpiDeviceState *state = SPI_DEVICE_TO_STATE(dev);
261 spiSlaveDone(state);
262 }
263
spiSlaveDone(struct SpiDeviceState * state)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
spiSetupRxTx(struct SpiDeviceState * state,const struct SpiPacket packets[],size_t n,SpiCbkF callback,void * cookie)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
spiMasterRequest(uint8_t busId,struct SpiDevice ** dev_out)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
spiMasterRxTx(struct SpiDevice * dev,spi_cs_t cs,const struct SpiPacket packets[],size_t n,const struct SpiMode * mode,SpiCbkF callback,void * cookie)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
spiMasterRelease(struct SpiDevice * dev)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
spiSlaveRequest(uint8_t busId,const struct SpiMode * mode,struct SpiDevice ** dev_out)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
spiSlaveRxTx(struct SpiDevice * dev,const struct SpiPacket packets[],size_t n,SpiCbkF callback,void * cookie)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
spiSlaveWaitForInactive(struct SpiDevice * dev,SpiCbkF callback,void * cookie)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
spiSlaveRelease(struct SpiDevice * dev)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