.. | .. |
---|
9 | 9 | #include <linux/device.h> |
---|
10 | 10 | #include <linux/mod_devicetable.h> |
---|
11 | 11 | #include <linux/slab.h> |
---|
| 12 | +#include <linux/dmaengine.h> |
---|
12 | 13 | #include <linux/kthread.h> |
---|
13 | 14 | #include <linux/completion.h> |
---|
14 | 15 | #include <linux/scatterlist.h> |
---|
.. | .. |
---|
253 | 254 | |
---|
254 | 255 | struct spi_message; |
---|
255 | 256 | struct spi_transfer; |
---|
| 257 | +struct spi_oob_transfer; |
---|
256 | 258 | |
---|
257 | 259 | /** |
---|
258 | 260 | * struct spi_driver - Host side "protocol" driver |
---|
.. | .. |
---|
352 | 354 | * @io_mutex: mutex for physical bus access |
---|
353 | 355 | * @bus_lock_spinlock: spinlock for SPI bus locking |
---|
354 | 356 | * @bus_lock_mutex: mutex for exclusion of multiple callers |
---|
| 357 | + * @bus_oob_lock_sem: semaphore for exclusion during oob operations |
---|
355 | 358 | * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use |
---|
356 | 359 | * @setup: updates the device mode and clocking records used by a |
---|
357 | 360 | * device's SPI controller; protocol code may call this. This |
---|
.. | .. |
---|
534 | 537 | spinlock_t bus_lock_spinlock; |
---|
535 | 538 | struct mutex bus_lock_mutex; |
---|
536 | 539 | |
---|
| 540 | +#ifdef CONFIG_SPI_OOB |
---|
| 541 | + struct semaphore bus_oob_lock_sem; |
---|
| 542 | +#endif |
---|
| 543 | + |
---|
537 | 544 | /* flag indicating that the SPI bus is locked for exclusive use */ |
---|
538 | 545 | bool bus_lock_flag; |
---|
539 | 546 | |
---|
.. | .. |
---|
626 | 633 | int (*unprepare_message)(struct spi_controller *ctlr, |
---|
627 | 634 | struct spi_message *message); |
---|
628 | 635 | int (*slave_abort)(struct spi_controller *ctlr); |
---|
| 636 | + int (*prepare_oob_transfer)(struct spi_controller *ctlr, |
---|
| 637 | + struct spi_oob_transfer *xfer); |
---|
| 638 | + void (*start_oob_transfer)(struct spi_controller *ctlr, |
---|
| 639 | + struct spi_oob_transfer *xfer); |
---|
| 640 | + void (*pulse_oob_transfer)(struct spi_controller *ctlr, |
---|
| 641 | + struct spi_oob_transfer *xfer); |
---|
| 642 | + void (*terminate_oob_transfer)(struct spi_controller *ctlr, |
---|
| 643 | + struct spi_oob_transfer *xfer); |
---|
629 | 644 | |
---|
630 | 645 | /* |
---|
631 | 646 | * These hooks are for drivers that use a generic implementation |
---|
.. | .. |
---|
1137 | 1152 | kfree(m); |
---|
1138 | 1153 | } |
---|
1139 | 1154 | |
---|
| 1155 | +struct spi_oob_transfer { |
---|
| 1156 | + struct spi_device *spi; |
---|
| 1157 | + dma_addr_t dma_addr; |
---|
| 1158 | + size_t aligned_frame_len; |
---|
| 1159 | + void *io_buffer; /* 2 x aligned_frame_len */ |
---|
| 1160 | + struct dma_async_tx_descriptor *txd; |
---|
| 1161 | + struct dma_async_tx_descriptor *rxd; |
---|
| 1162 | + u32 effective_speed_hz; |
---|
| 1163 | + /* |
---|
| 1164 | + * Caller-defined settings for the transfer. |
---|
| 1165 | + */ |
---|
| 1166 | + struct spi_oob_setup { |
---|
| 1167 | + u32 frame_len; |
---|
| 1168 | + u32 speed_hz; |
---|
| 1169 | + u8 bits_per_word; |
---|
| 1170 | + dma_async_tx_callback xfer_done; |
---|
| 1171 | + } setup; |
---|
| 1172 | +}; |
---|
| 1173 | + |
---|
| 1174 | +static inline off_t spi_get_oob_rxoff(struct spi_oob_transfer *xfer) |
---|
| 1175 | +{ |
---|
| 1176 | + /* RX area is in first half of the I/O buffer. */ |
---|
| 1177 | + return 0; |
---|
| 1178 | +} |
---|
| 1179 | + |
---|
| 1180 | +static inline off_t spi_get_oob_txoff(struct spi_oob_transfer *xfer) |
---|
| 1181 | +{ |
---|
| 1182 | + /* TX area is in second half of the I/O buffer. */ |
---|
| 1183 | + return xfer->aligned_frame_len; |
---|
| 1184 | +} |
---|
| 1185 | + |
---|
| 1186 | +static inline size_t spi_get_oob_iolen(struct spi_oob_transfer *xfer) |
---|
| 1187 | +{ |
---|
| 1188 | + return xfer->aligned_frame_len * 2; |
---|
| 1189 | +} |
---|
| 1190 | + |
---|
| 1191 | +#ifdef CONFIG_SPI_OOB |
---|
| 1192 | + |
---|
| 1193 | +struct vm_area_struct; |
---|
| 1194 | + |
---|
| 1195 | +int spi_prepare_oob_transfer(struct spi_device *spi, |
---|
| 1196 | + struct spi_oob_transfer *xfer); |
---|
| 1197 | + |
---|
| 1198 | +void spi_start_oob_transfer(struct spi_oob_transfer *xfer); |
---|
| 1199 | + |
---|
| 1200 | +int spi_pulse_oob_transfer(struct spi_oob_transfer *xfer); |
---|
| 1201 | + |
---|
| 1202 | +void spi_terminate_oob_transfer(struct spi_oob_transfer *xfer); |
---|
| 1203 | + |
---|
| 1204 | +int spi_mmap_oob_transfer(struct vm_area_struct *vma, |
---|
| 1205 | + struct spi_oob_transfer *xfer); |
---|
| 1206 | + |
---|
| 1207 | +#else |
---|
| 1208 | + |
---|
| 1209 | +static inline |
---|
| 1210 | +int spi_prepare_oob_transfer(struct spi_device *spi, |
---|
| 1211 | + struct spi_oob_transfer *xfer) |
---|
| 1212 | +{ |
---|
| 1213 | + return -ENOTSUPP; |
---|
| 1214 | +} |
---|
| 1215 | + |
---|
| 1216 | +static inline |
---|
| 1217 | +void spi_start_oob_transfer(struct spi_oob_transfer *xfer) |
---|
| 1218 | +{ } |
---|
| 1219 | + |
---|
| 1220 | +static inline |
---|
| 1221 | +int spi_pulse_oob_transfer(struct spi_oob_transfer *xfer) |
---|
| 1222 | +{ |
---|
| 1223 | + return -EIO; |
---|
| 1224 | +} |
---|
| 1225 | + |
---|
| 1226 | +static inline |
---|
| 1227 | +void spi_terminate_oob_transfer(struct spi_oob_transfer *xfer) |
---|
| 1228 | +{ } |
---|
| 1229 | + |
---|
| 1230 | +static inline |
---|
| 1231 | +int spi_mmap_oob_transfer(struct vm_area_struct *vma, |
---|
| 1232 | + struct spi_oob_transfer *xfer) |
---|
| 1233 | +{ |
---|
| 1234 | + return -ENXIO; |
---|
| 1235 | +} |
---|
| 1236 | + |
---|
| 1237 | +#endif |
---|
| 1238 | + |
---|
1140 | 1239 | extern int spi_set_cs_timing(struct spi_device *spi, |
---|
1141 | 1240 | struct spi_delay *setup, |
---|
1142 | 1241 | struct spi_delay *hold, |
---|