1 /* 2 * Perform SPI communication using the JZ4780 SPI peripheral. 3 * 4 * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #pragma once 23 24 #include <l4/re/c/dma_space.h> 25 #include <l4/sys/types.h> 26 #include <stdint.h> 27 28 29 30 #ifdef __cplusplus 31 32 #include <l4/devices/cpm-jz4780.h> 33 #include <l4/devices/dma-jz4780.h> 34 #include <l4/devices/hw_mmio_register_block.h> 35 #include <l4/devices/spi.h> 36 37 /* SPI peripheral channel. */ 38 39 class Spi_jz4780_channel : public Spi_channel_base 40 { 41 Hw::Register_block<32> _regs; 42 43 /* Initialisation parameters. */ 44 45 l4_addr_t _spi_start; 46 enum Clock_identifiers _clock; 47 Cpm_jz4780_chip *_cpm; 48 Dma_jz4780_channel *_dma; 49 enum Dma_jz4780_request_type _request_type; 50 uint64_t _frequency; 51 52 /* Common utilities. */ 53 54 void configure_transfer(uint8_t char_size); 55 56 void wait_busy(); 57 58 public: 59 explicit Spi_jz4780_channel(l4_addr_t spi_start, l4_addr_t start, 60 enum Clock_identifiers clock, 61 Cpm_jz4780_chip *cpm, 62 Dma_jz4780_channel *dma, 63 enum Dma_jz4780_request_type request_type, 64 uint64_t frequency); 65 66 /* Convenience operations. */ 67 68 virtual uint32_t send(uint32_t bytes, const uint8_t data[]); 69 70 virtual uint32_t send_dc(uint32_t bytes, const uint8_t data[], const int dc[]); 71 72 uint32_t send_units(uint32_t bytes, const uint8_t data[], uint8_t unit_size, 73 uint8_t char_size); 74 75 /* DMA operations. */ 76 77 uint32_t transfer(l4re_dma_space_dma_addr_t paddr, uint32_t count, 78 uint8_t unit_size, uint8_t char_size); 79 }; 80 81 /* SPI peripheral. */ 82 83 class Spi_jz4780_chip 84 { 85 private: 86 l4_addr_t _spi_start, _start, _end; 87 Cpm_jz4780_chip *_cpm; 88 89 public: 90 explicit Spi_jz4780_chip(l4_addr_t spi_start, l4_addr_t start, l4_addr_t end, Cpm_jz4780_chip *cpm); 91 92 Spi_jz4780_channel *get_channel(uint8_t channel, Dma_jz4780_channel *dma, uint64_t frequency); 93 }; 94 95 #endif /* __cplusplus */ 96 97 98 99 /* C language interface. */ 100 101 EXTERN_C_BEGIN 102 103 void *jz4780_spi_init(l4_addr_t spi_start, l4_addr_t start, l4_addr_t end, 104 void *cpm); 105 106 void *jz4780_spi_get_channel(void *spi, uint8_t channel, void *dma, uint64_t frequency); 107 108 uint32_t jz4780_spi_send(void *channel, uint32_t bytes, const uint8_t data[]); 109 110 uint32_t jz4780_spi_send_dc(void *channel, uint32_t bytes, const uint8_t data[], 111 const int dc[]); 112 113 uint32_t jz4780_spi_send_units(void *channel, uint32_t bytes, const uint8_t data[], 114 uint8_t unit_size, uint8_t char_size); 115 116 uint32_t jz4780_spi_transfer(void *channel, l4re_dma_space_dma_addr_t paddr, 117 uint32_t count, uint8_t unit_size, uint8_t char_size); 118 119 EXTERN_C_END