1 /* 2 * I2C support for the X1600. 3 * 4 * Copyright (C) 2017, 2018, 2019, 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/sys/types.h> 25 #include <stdint.h> 26 27 28 29 #ifdef __cplusplus 30 31 #include <l4/devices/cpm-x1600.h> 32 #include <l4/devices/hw_mmio_register_block.h> 33 34 // I2C channel. 35 36 class I2c_x1600_channel 37 { 38 private: 39 Hw::Register_block<32> _regs; 40 Cpm_x1600_chip *_cpm; 41 uint32_t _frequency; 42 43 // Buffer management. 44 45 unsigned int _pos, _reqpos, _total; 46 uint8_t *_buf; 47 48 // Status conditions. 49 50 int _fail; 51 int _stop; 52 53 public: 54 I2c_x1600_channel(l4_addr_t start, enum Clock_identifiers clock, 55 Cpm_x1600_chip *cpm, uint32_t frequency); 56 57 uint32_t get_frequency(); 58 void set_target(uint8_t addr); 59 60 // Reading initiation and execution. 61 62 void start_read(uint8_t buf[], unsigned int total, int stop = 0); 63 void read(); 64 65 // Writing initiation and execution. 66 67 void start_write(uint8_t buf[], unsigned int total, int stop = 0); 68 void write(); 69 70 // Transaction control. 71 72 void stop(); 73 void disable(); 74 75 // Specific status conditions. 76 77 unsigned int have_read(); 78 unsigned int have_written(); 79 int read_done(); 80 int write_done(); 81 82 int failed(); 83 int read_failed(); 84 int write_failed(); 85 86 private: 87 void enable(); 88 89 int active(); 90 int have_input(); 91 int have_output(); 92 int can_send(); 93 94 void reset_flags(); 95 void init_parameters(); 96 void set_frequency(); 97 98 void set_read_threshold(); 99 void queue_reads(); 100 void queue_writes(); 101 void store_reads(); 102 }; 103 104 // I2C device control. 105 106 class I2c_x1600_chip 107 { 108 private: 109 l4_addr_t _start, _end; 110 Cpm_x1600_chip *_cpm; 111 uint32_t _frequency; 112 113 public: 114 I2c_x1600_chip(l4_addr_t start, l4_addr_t end, Cpm_x1600_chip *cpm, 115 uint32_t frequency); 116 117 I2c_x1600_channel *get_channel(uint8_t channel); 118 }; 119 120 #endif /* __cplusplus */ 121 122 123 124 /* C language interface. */ 125 126 EXTERN_C_BEGIN 127 128 void *x1600_i2c_init(l4_addr_t start, l4_addr_t end, void *cpm, 129 uint32_t frequency); 130 131 void *x1600_i2c_get_channel(void *i2c, uint8_t channel); 132 133 uint32_t x1600_i2c_get_frequency(void *i2c_channel); 134 135 void x1600_i2c_set_target(void *i2c_channel, uint8_t addr); 136 137 void x1600_i2c_start_read(void *i2c_channel, uint8_t buf[], unsigned int total, 138 int stop); 139 140 void x1600_i2c_read(void *i2c_channel); 141 142 void x1600_i2c_start_write(void *i2c_channel, uint8_t buf[], unsigned int total, 143 int stop); 144 145 void x1600_i2c_write(void *i2c_channel); 146 147 int x1600_i2c_read_done(void *i2c_channel); 148 149 int x1600_i2c_write_done(void *i2c_channel); 150 151 unsigned int x1600_i2c_have_read(void *i2c_channel); 152 153 unsigned int x1600_i2c_have_written(void *i2c_channel); 154 155 int x1600_i2c_failed(void *i2c_channel); 156 157 EXTERN_C_END