1 /* 2 * Perform SPI communication using a suitable abstraction augmented with 3 * explicit manipulation of a control signal. 4 * 5 * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA 21 */ 22 23 #pragma once 24 25 #include <l4/re/c/dma_space.h> 26 #include <stdint.h> 27 28 29 30 #ifdef __cplusplus 31 32 #include <l4/devices/gpio.h> 33 #include <l4/devices/spi.h> 34 35 /* SPI channel abstraction. */ 36 37 class Spi_hybrid : public Spi_channel_base, public Spi_control_base 38 { 39 Spi_channel_base *_channel; 40 Hw::Gpio_chip *_control_device; 41 int _control_pin; 42 int _control_alt_func; 43 44 public: 45 explicit Spi_hybrid(Spi_channel_base *channel, 46 Hw::Gpio_chip *control_device, int control_pin, 47 int control_alt_func = -1); 48 49 Spi_channel_base *get_channel(); 50 51 void acquire_control(bool asserted); 52 53 void release_control(); 54 55 uint32_t send(uint32_t bytes, const uint8_t data[]); 56 57 uint32_t send_dc(uint32_t bytes, const uint8_t data[], const int dc[], 58 uint8_t char_size, bool big_endian); 59 60 uint32_t send_units(uint32_t bytes, const uint8_t data[], 61 uint8_t unit_size, uint8_t char_size, bool big_endian); 62 63 uint32_t transfer(l4_addr_t vaddr, l4re_dma_space_dma_addr_t paddr, 64 uint32_t count, uint8_t unit_size, uint8_t char_size, 65 l4_addr_t desc_vaddr = 0, 66 l4re_dma_space_dma_addr_t desc_paddr = 0); 67 }; 68 69 #endif /* __cplusplus */ 70 71 72 73 /* C language interface. */ 74 75 EXTERN_C_BEGIN 76 77 void *spi_hybrid_get_channel(void *channel, void *control_chip, int control_pin, 78 int control_alt_func); 79 80 void *spi_hybrid_get_raw_channel(void *channel); 81 82 void spi_hybrid_acquire_control(void *channel, int asserted); 83 84 void spi_hybrid_release_control(void *channel); 85 86 uint32_t spi_hybrid_send(void *channel, uint32_t bytes, const uint8_t data[]); 87 88 uint32_t spi_hybrid_send_dc(void *channel, uint32_t bytes, const uint8_t data[], 89 const int dc[], uint8_t char_size, int big_endian); 90 91 uint32_t spi_hybrid_send_units(void *channel, uint32_t bytes, const uint8_t data[], 92 uint8_t unit_size, uint8_t char_size, int big_endian); 93 94 uint32_t spi_hybrid_transfer(void *channel, l4_addr_t vaddr, 95 l4re_dma_space_dma_addr_t paddr, uint32_t count, 96 uint8_t unit_size, uint8_t char_size); 97 98 uint32_t spi_hybrid_transfer_descriptor(void *channel, l4_addr_t vaddr, 99 l4re_dma_space_dma_addr_t paddr, 100 uint32_t count, uint8_t unit_size, 101 uint8_t char_size, l4_addr_t desc_vaddr, 102 l4re_dma_space_dma_addr_t desc_paddr); 103 104 EXTERN_C_END