^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2018 Exceet Electronics GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2018 Bootlin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Boris Brezillon <boris.brezillon@bootlin.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/dmaengine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/spi/spi-mem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "internals.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define SPI_MEM_MAX_BUSWIDTH 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * spi_controller_dma_map_mem_op_data() - DMA-map the buffer attached to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * memory operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * @ctlr: the SPI controller requesting this dma_map()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * @op: the memory operation containing the buffer to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * @sgt: a pointer to a non-initialized sg_table that will be filled by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Some controllers might want to do DMA on the data buffer embedded in @op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * This helper prepares everything for you and provides a ready-to-use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * sg_table. This function is not intended to be called from spi drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Only SPI controller drivers should use it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Note that the caller must ensure the memory region pointed by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * op->data.buf.{in,out} is DMA-able before calling this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * Return: 0 in case of success, a negative error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) const struct spi_mem_op *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct sg_table *sgt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct device *dmadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (!op->data.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (op->data.dir == SPI_MEM_DATA_OUT && ctlr->dma_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) dmadev = ctlr->dma_tx->device->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) else if (op->data.dir == SPI_MEM_DATA_IN && ctlr->dma_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) dmadev = ctlr->dma_rx->device->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dmadev = ctlr->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (!dmadev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return spi_map_buf(ctlr, dmadev, sgt, op->data.buf.in, op->data.nbytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) op->data.dir == SPI_MEM_DATA_IN ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) DMA_FROM_DEVICE : DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) EXPORT_SYMBOL_GPL(spi_controller_dma_map_mem_op_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * spi_controller_dma_unmap_mem_op_data() - DMA-unmap the buffer attached to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * memory operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * @ctlr: the SPI controller requesting this dma_unmap()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @op: the memory operation containing the buffer to unmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * @sgt: a pointer to an sg_table previously initialized by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * spi_controller_dma_map_mem_op_data()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Some controllers might want to do DMA on the data buffer embedded in @op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * This helper prepares things so that the CPU can access the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * op->data.buf.{in,out} buffer again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * This function is not intended to be called from SPI drivers. Only SPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * controller drivers should use it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * This function should be called after the DMA operation has finished and is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * only valid if the previous spi_controller_dma_map_mem_op_data() call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * returned 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * Return: 0 in case of success, a negative error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) void spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) const struct spi_mem_op *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct sg_table *sgt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct device *dmadev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (!op->data.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (op->data.dir == SPI_MEM_DATA_OUT && ctlr->dma_tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) dmadev = ctlr->dma_tx->device->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) else if (op->data.dir == SPI_MEM_DATA_IN && ctlr->dma_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) dmadev = ctlr->dma_rx->device->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) dmadev = ctlr->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) spi_unmap_buf(ctlr, dmadev, sgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) op->data.dir == SPI_MEM_DATA_IN ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) DMA_FROM_DEVICE : DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) EXPORT_SYMBOL_GPL(spi_controller_dma_unmap_mem_op_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int spi_check_buswidth_req(struct spi_mem *mem, u8 buswidth, bool tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u32 mode = mem->spi->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) switch (buswidth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if ((tx &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) (mode & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) (!tx &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) (mode & (SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if ((tx && (mode & (SPI_TX_QUAD | SPI_TX_OCTAL))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) (!tx && (mode & (SPI_RX_QUAD | SPI_RX_OCTAL))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if ((tx && (mode & SPI_TX_OCTAL)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) (!tx && (mode & SPI_RX_OCTAL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static bool spi_mem_check_buswidth(struct spi_mem *mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) const struct spi_mem_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (spi_check_buswidth_req(mem, op->cmd.buswidth, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (op->addr.nbytes &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) spi_check_buswidth_req(mem, op->addr.buswidth, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (op->dummy.nbytes &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) spi_check_buswidth_req(mem, op->dummy.buswidth, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (op->data.dir != SPI_MEM_NO_DATA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) spi_check_buswidth_req(mem, op->data.buswidth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) op->data.dir == SPI_MEM_DATA_OUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) bool spi_mem_dtr_supports_op(struct spi_mem *mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) const struct spi_mem_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (op->cmd.nbytes != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return spi_mem_check_buswidth(mem, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) EXPORT_SYMBOL_GPL(spi_mem_dtr_supports_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) bool spi_mem_default_supports_op(struct spi_mem *mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) const struct spi_mem_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (op->cmd.nbytes != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return spi_mem_check_buswidth(mem, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) EXPORT_SYMBOL_GPL(spi_mem_default_supports_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static bool spi_mem_buswidth_is_valid(u8 buswidth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (hweight8(buswidth) > 1 || buswidth > SPI_MEM_MAX_BUSWIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int spi_mem_check_op(const struct spi_mem_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!op->cmd.buswidth || !op->cmd.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if ((op->addr.nbytes && !op->addr.buswidth) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) (op->dummy.nbytes && !op->dummy.buswidth) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) (op->data.nbytes && !op->data.buswidth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (!spi_mem_buswidth_is_valid(op->cmd.buswidth) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) !spi_mem_buswidth_is_valid(op->addr.buswidth) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) !spi_mem_buswidth_is_valid(op->dummy.buswidth) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) !spi_mem_buswidth_is_valid(op->data.buswidth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static bool spi_mem_internal_supports_op(struct spi_mem *mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) const struct spi_mem_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct spi_controller *ctlr = mem->spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ctlr->mem_ops && ctlr->mem_ops->supports_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return ctlr->mem_ops->supports_op(mem, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return spi_mem_default_supports_op(mem, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * spi_mem_supports_op() - Check if a memory device and the controller it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * connected to support a specific memory operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * @mem: the SPI memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * @op: the memory operation to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * Some controllers are only supporting Single or Dual IOs, others might only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * support specific opcodes, or it can even be that the controller and device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * both support Quad IOs but the hardware prevents you from using it because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * only 2 IO lines are connected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * This function checks whether a specific operation is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * Return: true if @op is supported, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) bool spi_mem_supports_op(struct spi_mem *mem, const struct spi_mem_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (spi_mem_check_op(op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return spi_mem_internal_supports_op(mem, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) EXPORT_SYMBOL_GPL(spi_mem_supports_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int spi_mem_access_start(struct spi_mem *mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct spi_controller *ctlr = mem->spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * Flush the message queue before executing our SPI memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * operation to prevent preemption of regular SPI transfers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) spi_flush_queue(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (ctlr->auto_runtime_pm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ret = pm_runtime_get_sync(ctlr->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) pm_runtime_put_noidle(ctlr->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) dev_err(&ctlr->dev, "Failed to power device: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) mutex_lock(&ctlr->bus_lock_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) mutex_lock(&ctlr->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static void spi_mem_access_end(struct spi_mem *mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct spi_controller *ctlr = mem->spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) mutex_unlock(&ctlr->io_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mutex_unlock(&ctlr->bus_lock_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (ctlr->auto_runtime_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) pm_runtime_put(ctlr->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * spi_mem_exec_op() - Execute a memory operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * @mem: the SPI memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * @op: the memory operation to execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * Executes a memory operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * This function first checks that @op is supported and then tries to execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * Return: 0 in case of success, a negative error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) unsigned int tmpbufsize, xferpos = 0, totalxferlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct spi_controller *ctlr = mem->spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct spi_transfer xfers[4] = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct spi_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u8 *tmpbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ret = spi_mem_check_op(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!spi_mem_internal_supports_op(mem, op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (ctlr->mem_ops && !mem->spi->cs_gpiod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ret = spi_mem_access_start(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ret = ctlr->mem_ops->exec_op(mem, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) spi_mem_access_end(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * Some controllers only optimize specific paths (typically the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * read path) and expect the core to use the regular SPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * interface in other cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (!ret || ret != -ENOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) tmpbufsize = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * Allocate a buffer to transmit the CMD, ADDR cycles with kmalloc() so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * we're guaranteed that this buffer is DMA-able, as required by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * SPI layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) tmpbuf = kzalloc(tmpbufsize, GFP_KERNEL | GFP_DMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (!tmpbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) spi_message_init(&msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) tmpbuf[0] = op->cmd.opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) xfers[xferpos].tx_buf = tmpbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) xfers[xferpos].len = op->cmd.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) xfers[xferpos].tx_nbits = op->cmd.buswidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) spi_message_add_tail(&xfers[xferpos], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) xferpos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) totalxferlen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (op->addr.nbytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) for (i = 0; i < op->addr.nbytes; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) tmpbuf[i + 1] = op->addr.val >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) (8 * (op->addr.nbytes - i - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) xfers[xferpos].tx_buf = tmpbuf + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) xfers[xferpos].len = op->addr.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) xfers[xferpos].tx_nbits = op->addr.buswidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) spi_message_add_tail(&xfers[xferpos], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) xferpos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) totalxferlen += op->addr.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (op->dummy.nbytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) memset(tmpbuf + op->addr.nbytes + 1, 0xff, op->dummy.nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) xfers[xferpos].tx_buf = tmpbuf + op->addr.nbytes + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) xfers[xferpos].len = op->dummy.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) xfers[xferpos].tx_nbits = op->dummy.buswidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) spi_message_add_tail(&xfers[xferpos], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) xferpos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) totalxferlen += op->dummy.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (op->data.nbytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (op->data.dir == SPI_MEM_DATA_IN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) xfers[xferpos].rx_buf = op->data.buf.in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) xfers[xferpos].rx_nbits = op->data.buswidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) xfers[xferpos].tx_buf = op->data.buf.out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) xfers[xferpos].tx_nbits = op->data.buswidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) xfers[xferpos].len = op->data.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) spi_message_add_tail(&xfers[xferpos], &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) xferpos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) totalxferlen += op->data.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ret = spi_sync(mem->spi, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) kfree(tmpbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (msg.actual_length != totalxferlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) EXPORT_SYMBOL_GPL(spi_mem_exec_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * spi_mem_get_name() - Return the SPI mem device name to be used by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * upper layer if necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * @mem: the SPI memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * This function allows SPI mem users to retrieve the SPI mem device name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * It is useful if the upper layer needs to expose a custom name for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * compatibility reasons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * Return: a string containing the name of the memory device to be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * by the SPI mem user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) const char *spi_mem_get_name(struct spi_mem *mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return mem->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) EXPORT_SYMBOL_GPL(spi_mem_get_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * spi_mem_adjust_op_size() - Adjust the data size of a SPI mem operation to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * match controller limitations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * @mem: the SPI memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * @op: the operation to adjust
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * Some controllers have FIFO limitations and must split a data transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * operation into multiple ones, others require a specific alignment for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * optimized accesses. This function allows SPI mem drivers to split a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * operation into multiple sub-operations when required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * Return: a negative error code if the controller can't properly adjust @op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * 0 otherwise. Note that @op->data.nbytes will be updated if @op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * can't be handled in a single step.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct spi_controller *ctlr = mem->spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return ctlr->mem_ops->adjust_op_size(mem, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (len > spi_max_transfer_size(mem->spi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) op->data.nbytes = min3((size_t)op->data.nbytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) spi_max_transfer_size(mem->spi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) spi_max_message_size(mem->spi) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (!op->data.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) u64 offs, size_t len, void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct spi_mem_op op = desc->info.op_tmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) op.addr.val = desc->info.offset + offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) op.data.buf.in = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) op.data.nbytes = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = spi_mem_adjust_op_size(desc->mem, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ret = spi_mem_exec_op(desc->mem, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return op.data.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u64 offs, size_t len, const void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct spi_mem_op op = desc->info.op_tmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) op.addr.val = desc->info.offset + offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) op.data.buf.out = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) op.data.nbytes = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ret = spi_mem_adjust_op_size(desc->mem, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ret = spi_mem_exec_op(desc->mem, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return op.data.nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * spi_mem_dirmap_create() - Create a direct mapping descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * @mem: SPI mem device this direct mapping should be created for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * @info: direct mapping information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * This function is creating a direct mapping descriptor which can then be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * to access the memory using spi_mem_dirmap_read() or spi_mem_dirmap_write().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * If the SPI controller driver does not support direct mapping, this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * falls back to an implementation using spi_mem_exec_op(), so that the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * doesn't have to bother implementing a fallback on his own.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * Return: a valid pointer in case of success, and ERR_PTR() otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct spi_mem_dirmap_desc *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) spi_mem_dirmap_create(struct spi_mem *mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) const struct spi_mem_dirmap_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct spi_controller *ctlr = mem->spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct spi_mem_dirmap_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int ret = -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* Make sure the number of address cycles is between 1 and 8 bytes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) desc = kzalloc(sizeof(*desc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) desc->mem = mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) desc->info = *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (ctlr->mem_ops && ctlr->mem_ops->dirmap_create)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) ret = ctlr->mem_ops->dirmap_create(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) desc->nodirmap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (!spi_mem_supports_op(desc->mem, &desc->info.op_tmpl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ret = -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) kfree(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) EXPORT_SYMBOL_GPL(spi_mem_dirmap_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * spi_mem_dirmap_destroy() - Destroy a direct mapping descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * @desc: the direct mapping descriptor to destroy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * This function destroys a direct mapping descriptor previously created by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * spi_mem_dirmap_create().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) void spi_mem_dirmap_destroy(struct spi_mem_dirmap_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct spi_controller *ctlr = desc->mem->spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (!desc->nodirmap && ctlr->mem_ops && ctlr->mem_ops->dirmap_destroy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ctlr->mem_ops->dirmap_destroy(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) kfree(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) EXPORT_SYMBOL_GPL(spi_mem_dirmap_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static void devm_spi_mem_dirmap_release(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct spi_mem_dirmap_desc *desc = *(struct spi_mem_dirmap_desc **)res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) spi_mem_dirmap_destroy(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * devm_spi_mem_dirmap_create() - Create a direct mapping descriptor and attach
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * it to a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * @dev: device the dirmap desc will be attached to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * @mem: SPI mem device this direct mapping should be created for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * @info: direct mapping information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * devm_ variant of the spi_mem_dirmap_create() function. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * spi_mem_dirmap_create() for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * Return: a valid pointer in case of success, and ERR_PTR() otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) struct spi_mem_dirmap_desc *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) devm_spi_mem_dirmap_create(struct device *dev, struct spi_mem *mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) const struct spi_mem_dirmap_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct spi_mem_dirmap_desc **ptr, *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ptr = devres_alloc(devm_spi_mem_dirmap_release, sizeof(*ptr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (!ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) desc = spi_mem_dirmap_create(mem, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (IS_ERR(desc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) devres_free(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) *ptr = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) devres_add(dev, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) EXPORT_SYMBOL_GPL(devm_spi_mem_dirmap_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int devm_spi_mem_dirmap_match(struct device *dev, void *res, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct spi_mem_dirmap_desc **ptr = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (WARN_ON(!ptr || !*ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return *ptr == data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * devm_spi_mem_dirmap_destroy() - Destroy a direct mapping descriptor attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * to a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * @dev: device the dirmap desc is attached to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * @desc: the direct mapping descriptor to destroy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * devm_ variant of the spi_mem_dirmap_destroy() function. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * spi_mem_dirmap_destroy() for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) void devm_spi_mem_dirmap_destroy(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct spi_mem_dirmap_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) devres_release(dev, devm_spi_mem_dirmap_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) devm_spi_mem_dirmap_match, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) EXPORT_SYMBOL_GPL(devm_spi_mem_dirmap_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * spi_mem_dirmap_read() - Read data through a direct mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * @desc: direct mapping descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * @offs: offset to start reading from. Note that this is not an absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * offset, but the offset within the direct mapping which already has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * its own offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * @len: length in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * @buf: destination buffer. This buffer must be DMA-able
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * This function reads data from a memory device using a direct mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * previously instantiated with spi_mem_dirmap_create().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * Return: the amount of data read from the memory device or a negative error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * code. Note that the returned size might be smaller than @len, and the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * is responsible for calling spi_mem_dirmap_read() again when that happens.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) u64 offs, size_t len, void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct spi_controller *ctlr = desc->mem->spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (desc->nodirmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) ret = spi_mem_no_dirmap_read(desc, offs, len, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) } else if (ctlr->mem_ops && ctlr->mem_ops->dirmap_read) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ret = spi_mem_access_start(desc->mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ret = ctlr->mem_ops->dirmap_read(desc, offs, len, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) spi_mem_access_end(desc->mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) ret = -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) EXPORT_SYMBOL_GPL(spi_mem_dirmap_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * spi_mem_dirmap_write() - Write data through a direct mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * @desc: direct mapping descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * @offs: offset to start writing from. Note that this is not an absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * offset, but the offset within the direct mapping which already has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * its own offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * @len: length in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * @buf: source buffer. This buffer must be DMA-able
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * This function writes data to a memory device using a direct mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * previously instantiated with spi_mem_dirmap_create().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * Return: the amount of data written to the memory device or a negative error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * code. Note that the returned size might be smaller than @len, and the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * is responsible for calling spi_mem_dirmap_write() again when that happens.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ssize_t spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) u64 offs, size_t len, const void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct spi_controller *ctlr = desc->mem->spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (desc->nodirmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ret = spi_mem_no_dirmap_write(desc, offs, len, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) } else if (ctlr->mem_ops && ctlr->mem_ops->dirmap_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ret = spi_mem_access_start(desc->mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ret = ctlr->mem_ops->dirmap_write(desc, offs, len, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) spi_mem_access_end(desc->mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ret = -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) EXPORT_SYMBOL_GPL(spi_mem_dirmap_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static inline struct spi_mem_driver *to_spi_mem_drv(struct device_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return container_of(drv, struct spi_mem_driver, spidrv.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static int spi_mem_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct spi_mem_driver *memdrv = to_spi_mem_drv(spi->dev.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct spi_controller *ctlr = spi->controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct spi_mem *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) mem = devm_kzalloc(&spi->dev, sizeof(*mem), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (!mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) mem->spi = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (ctlr->mem_ops && ctlr->mem_ops->get_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) mem->name = ctlr->mem_ops->get_name(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) mem->name = dev_name(&spi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (IS_ERR_OR_NULL(mem->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return PTR_ERR(mem->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) spi_set_drvdata(spi, mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return memdrv->probe(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int spi_mem_remove(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct spi_mem_driver *memdrv = to_spi_mem_drv(spi->dev.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct spi_mem *mem = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (memdrv->remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return memdrv->remove(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static void spi_mem_shutdown(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct spi_mem_driver *memdrv = to_spi_mem_drv(spi->dev.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct spi_mem *mem = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (memdrv->shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) memdrv->shutdown(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * spi_mem_driver_register_with_owner() - Register a SPI memory driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * @memdrv: the SPI memory driver to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * @owner: the owner of this driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * Registers a SPI memory driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * Return: 0 in case of success, a negative error core otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) int spi_mem_driver_register_with_owner(struct spi_mem_driver *memdrv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct module *owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) memdrv->spidrv.probe = spi_mem_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) memdrv->spidrv.remove = spi_mem_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) memdrv->spidrv.shutdown = spi_mem_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return __spi_register_driver(owner, &memdrv->spidrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) EXPORT_SYMBOL_GPL(spi_mem_driver_register_with_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * spi_mem_driver_unregister_with_owner() - Unregister a SPI memory driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * @memdrv: the SPI memory driver to unregister
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * Unregisters a SPI memory driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) void spi_mem_driver_unregister(struct spi_mem_driver *memdrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) spi_unregister_driver(&memdrv->spidrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) EXPORT_SYMBOL_GPL(spi_mem_driver_unregister);