Lionel Debieve | 094ab3d | 2019-09-24 17:38:12 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2019, STMicroelectronics - All Rights Reserved |
| 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | |
| 7 | #ifndef DRIVERS_SPI_MEM_H |
| 8 | #define DRIVERS_SPI_MEM_H |
| 9 | |
| 10 | #include <errno.h> |
| 11 | #include <stdbool.h> |
| 12 | #include <stdint.h> |
| 13 | |
| 14 | #define SPI_MEM_BUSWIDTH_1_LINE 1U |
| 15 | #define SPI_MEM_BUSWIDTH_2_LINE 2U |
| 16 | #define SPI_MEM_BUSWIDTH_4_LINE 4U |
| 17 | |
| 18 | /* |
| 19 | * enum spi_mem_data_dir - Describes the direction of a SPI memory data |
| 20 | * transfer from the controller perspective. |
| 21 | * @SPI_MEM_DATA_IN: data coming from the SPI memory. |
| 22 | * @SPI_MEM_DATA_OUT: data sent to the SPI memory. |
| 23 | */ |
| 24 | enum spi_mem_data_dir { |
| 25 | SPI_MEM_DATA_IN, |
| 26 | SPI_MEM_DATA_OUT, |
| 27 | }; |
| 28 | |
| 29 | /* |
| 30 | * struct spi_mem_op - Describes a SPI memory operation. |
| 31 | * |
| 32 | * @cmd.buswidth: Number of IO lines used to transmit the command. |
| 33 | * @cmd.opcode: Operation opcode. |
| 34 | * @addr.nbytes: Number of address bytes to send. Can be zero if the operation |
| 35 | * does not need to send an address. |
| 36 | * @addr.buswidth: Number of IO lines used to transmit the address. |
| 37 | * @addr.val: Address value. This value is always sent MSB first on the bus. |
| 38 | * Note that only @addr.nbytes are taken into account in this |
| 39 | * address value, so users should make sure the value fits in the |
| 40 | * assigned number of bytes. |
| 41 | * @dummy.nbytes: Number of dummy bytes to send after an opcode or address. Can |
| 42 | * be zero if the operation does not require dummy bytes. |
| 43 | * @dummy.buswidth: Number of IO lines used to transmit the dummy bytes. |
| 44 | * @data.buswidth: Number of IO lines used to send/receive the data. |
| 45 | * @data.dir: Direction of the transfer. |
| 46 | * @data.nbytes: Number of data bytes to transfer. |
| 47 | * @data.buf: Input or output data buffer depending on data::dir. |
| 48 | */ |
| 49 | struct spi_mem_op { |
| 50 | struct { |
| 51 | uint8_t buswidth; |
| 52 | uint8_t opcode; |
| 53 | } cmd; |
| 54 | |
| 55 | struct { |
| 56 | uint8_t nbytes; |
| 57 | uint8_t buswidth; |
| 58 | uint64_t val; |
| 59 | } addr; |
| 60 | |
| 61 | struct { |
| 62 | uint8_t nbytes; |
| 63 | uint8_t buswidth; |
| 64 | } dummy; |
| 65 | |
| 66 | struct { |
| 67 | uint8_t buswidth; |
| 68 | enum spi_mem_data_dir dir; |
| 69 | unsigned int nbytes; |
| 70 | void *buf; |
| 71 | } data; |
| 72 | }; |
| 73 | |
| 74 | /* SPI mode flags */ |
| 75 | #define SPI_CPHA BIT(0) /* clock phase */ |
| 76 | #define SPI_CPOL BIT(1) /* clock polarity */ |
| 77 | #define SPI_CS_HIGH BIT(2) /* CS active high */ |
| 78 | #define SPI_LSB_FIRST BIT(3) /* per-word bits-on-wire */ |
| 79 | #define SPI_3WIRE BIT(4) /* SI/SO signals shared */ |
| 80 | #define SPI_PREAMBLE BIT(5) /* Skip preamble bytes */ |
| 81 | #define SPI_TX_DUAL BIT(6) /* transmit with 2 wires */ |
| 82 | #define SPI_TX_QUAD BIT(7) /* transmit with 4 wires */ |
| 83 | #define SPI_RX_DUAL BIT(8) /* receive with 2 wires */ |
| 84 | #define SPI_RX_QUAD BIT(9) /* receive with 4 wires */ |
| 85 | |
| 86 | struct spi_bus_ops { |
| 87 | /* |
| 88 | * Claim the bus and prepare it for communication. |
| 89 | * |
| 90 | * @cs: The chip select. |
| 91 | * Returns: 0 if the bus was claimed successfully, or a negative value |
| 92 | * if it wasn't. |
| 93 | */ |
| 94 | int (*claim_bus)(unsigned int cs); |
| 95 | |
| 96 | /* |
| 97 | * Release the SPI bus. |
| 98 | */ |
| 99 | void (*release_bus)(void); |
| 100 | |
| 101 | /* |
| 102 | * Set transfer speed. |
| 103 | * |
| 104 | * @hz: The transfer speed in Hertz. |
| 105 | * Returns: 0 on success, a negative error code otherwise. |
| 106 | */ |
| 107 | int (*set_speed)(unsigned int hz); |
| 108 | |
| 109 | /* |
| 110 | * Set the SPI mode/flags. |
| 111 | * |
| 112 | * @mode: Requested SPI mode (SPI_... flags). |
| 113 | * Returns: 0 on success, a negative error code otherwise. |
| 114 | */ |
| 115 | int (*set_mode)(unsigned int mode); |
| 116 | |
| 117 | /* |
| 118 | * Execute a SPI memory operation. |
| 119 | * |
| 120 | * @op: The memory operation to execute. |
| 121 | * Returns: 0 on success, a negative error code otherwise. |
| 122 | */ |
| 123 | int (*exec_op)(const struct spi_mem_op *op); |
| 124 | }; |
| 125 | |
| 126 | int spi_mem_exec_op(const struct spi_mem_op *op); |
| 127 | int spi_mem_init_slave(void *fdt, int bus_node, |
| 128 | const struct spi_bus_ops *ops); |
| 129 | |
| 130 | #endif /* DRIVERS_SPI_MEM_H */ |