1 /* 2 * I2C support for the JZ4730. 3 * 4 * Copyright (C) 2017, 2018, 2020 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 #include <l4/devices/i2c-jz4730.h> 23 #include <l4/devices/hw_mmio_register_block.h> 24 25 #include <l4/sys/icu.h> 26 #include <l4/util/util.h> 27 28 #include <cstdio> 29 30 /* 31 I2C pins are dedicated to I2C only and are not GPIO-controlled: 32 33 I2C0: Y4/SMB0_SDA, V5/SMB0_SCK 34 35 Note that there is effectively only one I2C channel. 36 */ 37 38 enum Regs 39 { 40 I2c_data = 0x000, // I2CDR 41 I2c_control = 0x004, // I2CCR 42 I2c_status = 0x008, // I2CSR 43 I2c_clock = 0x00c, // I2CGR 44 }; 45 46 enum I2c_control_bits : unsigned 47 { 48 I2c_control_enable_irq = 0x10, // IEN 49 I2c_control_start = 0x08, // STA 50 I2c_control_stop = 0x04, // STO 51 I2c_control_nack = 0x02, // AC 52 I2c_control_enable = 0x01, // I2CE 53 }; 54 55 enum I2c_status_bits : unsigned 56 { 57 I2c_status_buffer_nempty = 0x10, // STX 58 I2c_status_busy = 0x08, // BUSY 59 I2c_status_transmit_end = 0x04, // TEND 60 I2c_status_data_valid = 0x02, // DRF 61 I2c_status_nack = 0x01, // ACKF 62 }; 63 64 enum I2c_clock_values : unsigned 65 { 66 I2c_clock_max = 0xffff, 67 I2c_clock_min = 0, 68 }; 69 70 71 72 // Initialise a channel. 73 74 I2c_jz4730_channel::I2c_jz4730_channel(l4_addr_t start, 75 Cpm_jz4730_chip *cpm, 76 uint32_t frequency) 77 : _cpm(cpm), _frequency(frequency) 78 { 79 _regs = new Hw::Mmio_register_block<32>(start); 80 } 81 82 // Enable the channel. 83 84 void 85 I2c_jz4730_channel::enable() 86 { 87 // Make sure that the I2C clock is available. 88 89 _cpm->start_i2c(); 90 91 // Set the bus clock frequency. 92 93 set_frequency(); 94 95 // Enable the channel and interrupts. 96 97 _regs[I2c_control] = I2c_control_enable | I2c_control_enable_irq; 98 while (!(_regs[I2c_control] & I2c_control_enable)); 99 } 100 101 // Disable the channel. 102 103 void 104 I2c_jz4730_channel::disable() 105 { 106 _regs[I2c_control] = 0; 107 while (_regs[I2c_control] & I2c_control_enable); 108 } 109 110 // Set the frequency-related peripheral parameters. 111 112 void 113 I2c_jz4730_channel::set_frequency() 114 { 115 // The APB clock (PCLK) is used to drive I2C transfers. Its value must be 116 // obtained from the CPM unit and is scaled to kHz in order to keep the 117 // numbers easily representable, as is the bus frequency. 118 119 uint32_t pclk = _cpm->get_pclock_frequency() / 1000; 120 uint32_t i2c_clk = _frequency / 1000; 121 uint32_t division = pclk / (16 * i2c_clk); 122 123 if (division > I2c_clock_min) 124 { 125 division -= 1; 126 if (division > I2c_clock_max) 127 division = I2c_clock_max; 128 } 129 130 _regs[I2c_clock] = division; 131 } 132 133 // Present the address on the bus. 134 135 void 136 I2c_jz4730_channel::set_address(uint8_t address, bool read) 137 { 138 start(); 139 140 while (nack()); 141 142 _regs[I2c_data] = (address << 1) | (read ? 1 : 0); 143 send_next(); 144 145 if (read) 146 while ((data_valid() || !transferred()) && !nack()); 147 else 148 while (data_valid() && !nack()); 149 } 150 151 // Read data from the bus. 152 153 unsigned int 154 I2c_jz4730_channel::read(uint8_t address, uint8_t buf[], unsigned int length) 155 { 156 unsigned int nread = 0; 157 158 set_address(address, true); 159 160 if (!nack()) 161 { 162 if (length == 1) 163 signal_last(); 164 165 while (nread < length) 166 { 167 while (!data_valid()); 168 169 if (nread == length - 2) 170 signal_last(); 171 172 buf[nread++] = _regs[I2c_data]; 173 request_next(); 174 } 175 } 176 177 stop(); 178 179 return nread; 180 } 181 182 // Write data to the bus. 183 184 unsigned int 185 I2c_jz4730_channel::write(uint8_t address, uint8_t buf[], unsigned int length) 186 { 187 unsigned int nwritten = 0; 188 189 set_address(address, false); 190 191 while ((nwritten < length) && !nack()) 192 { 193 _regs[I2c_data] = buf[nwritten++]; 194 send_next(); 195 196 while (data_valid() && !nack()); 197 } 198 199 stop(); 200 201 while (!transferred()); 202 203 return nwritten; 204 } 205 206 // Test for data validity. 207 208 bool 209 I2c_jz4730_channel::data_valid() 210 { 211 return (_regs[I2c_status] & I2c_status_data_valid) ? true : false; 212 } 213 214 // Request the next byte by clearing the data validity flag. 215 216 void 217 I2c_jz4730_channel::request_next() 218 { 219 _regs[I2c_status] = _regs[I2c_status] & ~I2c_status_data_valid; 220 } 221 222 // Indicate data ready for sending. 223 224 void 225 I2c_jz4730_channel::send_next() 226 { 227 _regs[I2c_status] = _regs[I2c_status] | I2c_status_data_valid; 228 } 229 230 // Test for non-acknowledgement. 231 232 bool 233 I2c_jz4730_channel::nack() 234 { 235 return (_regs[I2c_status] & I2c_status_nack) ? true : false; 236 } 237 238 // Set non-acknowledgement when receiving data. 239 240 void 241 I2c_jz4730_channel::signal_last() 242 { 243 _regs[I2c_control] = _regs[I2c_control] | I2c_control_nack; 244 } 245 246 // Test for write transfer completion. 247 248 bool 249 I2c_jz4730_channel::transferred() 250 { 251 return (_regs[I2c_status] & I2c_status_transmit_end) ? true : false; 252 } 253 254 // Explicitly start communication. 255 256 void 257 I2c_jz4730_channel::start() 258 { 259 _regs[I2c_control] = (_regs[I2c_control] & ~I2c_control_nack) | I2c_control_start; 260 } 261 262 // Explicitly stop communication. 263 264 void 265 I2c_jz4730_channel::stop() 266 { 267 _regs[I2c_control] = _regs[I2c_control] | I2c_control_stop; 268 } 269 270 271 272 // Initialise the I2C controller. 273 274 I2c_jz4730_chip::I2c_jz4730_chip(l4_addr_t start, l4_addr_t end, 275 Cpm_jz4730_chip *cpm, 276 uint32_t frequency) 277 : _start(start), _end(end), _cpm(cpm), _frequency(frequency) 278 { 279 } 280 281 // Obtain a channel object. Only one channel is supported. 282 283 I2c_jz4730_channel * 284 I2c_jz4730_chip::get_channel(uint8_t channel) 285 { 286 if (channel == 0) 287 return new I2c_jz4730_channel(_start, _cpm, _frequency); 288 else 289 throw -L4_EINVAL; 290 } 291 292 293 294 // C language interface functions. 295 296 void *jz4730_i2c_init(l4_addr_t start, l4_addr_t end, void *cpm, uint32_t frequency) 297 { 298 return (void *) new I2c_jz4730_chip(start, end, static_cast<Cpm_jz4730_chip *>(cpm), frequency); 299 } 300 301 void *jz4730_i2c_get_channel(void *i2c, uint8_t channel) 302 { 303 return static_cast<I2c_jz4730_chip *>(i2c)->get_channel(channel); 304 } 305 306 void jz4730_i2c_disable(void *i2c_channel) 307 { 308 static_cast<I2c_jz4730_channel *>(i2c_channel)->disable(); 309 } 310 311 void jz4730_i2c_enable(void *i2c_channel) 312 { 313 static_cast<I2c_jz4730_channel *>(i2c_channel)->enable(); 314 } 315 316 unsigned int jz4730_i2c_read(void *i2c_channel, uint8_t address, uint8_t buf[], unsigned int length) 317 { 318 return static_cast<I2c_jz4730_channel *>(i2c_channel)->read(address, buf, length); 319 } 320 321 unsigned int jz4730_i2c_write(void *i2c_channel, uint8_t address, uint8_t buf[], unsigned int length) 322 { 323 return static_cast<I2c_jz4730_channel *>(i2c_channel)->write(address, buf, length); 324 }