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 36 /* SPI peripheral channel. */ 37 38 class Spi_jz4780_channel 39 { 40 Hw::Register_block<32> _regs; 41 42 /* Initialisation parameters. */ 43 44 l4_addr_t _spi_start; 45 enum Clock_identifiers _clock; 46 Cpm_jz4780_chip *_cpm; 47 Dma_jz4780_channel *_dma; 48 enum Dma_jz4780_request_type _request_type; 49 uint64_t _frequency; 50 51 void configure_transfer(uint8_t char_size); 52 53 public: 54 explicit Spi_jz4780_channel(l4_addr_t spi_start, l4_addr_t start, 55 enum Clock_identifiers clock, 56 Cpm_jz4780_chip *cpm, 57 Dma_jz4780_channel *dma, 58 enum Dma_jz4780_request_type request_type, 59 uint64_t frequency); 60 61 /* DMA operations. */ 62 63 uint32_t transfer(l4re_dma_space_dma_addr_t paddr, uint32_t count, 64 uint8_t unit_size, uint8_t char_size); 65 66 /* Convenience operations. */ 67 68 uint32_t send(uint32_t bytes, const uint8_t data[], uint8_t unit_size, 69 uint8_t char_size); 70 }; 71 72 /* SPI peripheral. */ 73 74 class Spi_jz4780_chip 75 { 76 private: 77 l4_addr_t _spi_start, _start, _end; 78 Cpm_jz4780_chip *_cpm; 79 80 public: 81 explicit Spi_jz4780_chip(l4_addr_t spi_start, l4_addr_t start, l4_addr_t end, Cpm_jz4780_chip *cpm); 82 83 Spi_jz4780_channel *get_channel(uint8_t channel, Dma_jz4780_channel *dma, uint64_t frequency); 84 }; 85 86 #endif /* __cplusplus */ 87 88 89 90 /* C language interface. */ 91 92 EXTERN_C_BEGIN 93 94 void *jz4780_spi_init(l4_addr_t spi_start, l4_addr_t start, l4_addr_t end, 95 void *cpm); 96 97 void *jz4780_spi_get_channel(void *spi, uint8_t channel, void *dma, uint64_t frequency); 98 99 uint32_t jz4780_spi_send(void *channel, uint32_t bytes, const uint8_t data[], 100 uint8_t unit_size, uint8_t char_size); 101 102 uint32_t jz4780_spi_transfer(void *channel, l4re_dma_space_dma_addr_t paddr, 103 uint32_t count, uint8_t unit_size, uint8_t char_size); 104 105 EXTERN_C_END