1/* 2 * Copyright 2019, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13/* warning: use of callbacks is NOT tested with this driver */ 14 15#include <platsupport/i2c.h> 16#include <platsupport/pmem.h> 17#include <platsupport/plat/i2c.h> 18 19struct omap4_i2c_dev { 20 void *regs; 21 int irq_id; 22 enum i2c_slave_speed speed; 23 enum i2c_mode mode; 24 enum i2c_stat status; 25 uint16_t fifo_threshold; 26 uint8_t *buf; 27 size_t buf_len; 28 size_t buf_pos; 29 bool repeat_start; 30 bool interrupts_enabled; 31 volatile bool busy; 32}; 33typedef struct omap4_i2c_dev omap4_i2c_dev_t; 34 35static pmem_region_t pmems[] = { 36 { 37 .type = PMEM_TYPE_DEVICE, 38 .base_addr = AM335X_I2C0_PADDR, 39 .length = PAGE_SIZE_4K 40 }, 41 { 42 .type = PMEM_TYPE_DEVICE, 43 .base_addr = AM335X_I2C1_PADDR, 44 .length = PAGE_SIZE_4K 45 }, 46 { 47 .type = PMEM_TYPE_DEVICE, 48 .base_addr = AM335X_I2C2_PADDR, 49 .length = PAGE_SIZE_4K 50 } 51}; 52 53static ps_irq_t irqs[] = { 54 { 55 .type = PS_INTERRUPT, 56 .irq.number = AM335X_I2C0_IRQ 57 }, 58 { 59 .type = PS_INTERRUPT, 60 .irq.number = AM335X_I2C1_IRQ 61 }, 62 { 63 .type = PS_INTERRUPT, 64 .irq.number = AM335X_I2C2_IRQ 65 } 66}; 67 68static const uint32_t i2c_speed_freqs[] = { 69 [I2C_SLAVE_SPEED_STANDARD] = 100000, 70 [I2C_SLAVE_SPEED_FAST] = 400000 71}; 72 73static inline uint16_t omap4_i2c_reg_read(omap4_i2c_dev_t *dev, int addr) 74{ 75 return *(volatile uint16_t *)(dev->regs + addr); 76} 77 78static inline void omap4_i2c_reg_write(omap4_i2c_dev_t *dev, int addr, uint16_t val) 79{ 80 *(volatile uint16_t *)(dev->regs + addr) = val; 81} 82 83static void omap4_i2c_enable_interrupts(omap4_i2c_dev_t *dev) 84{ 85 dev->interrupts_enabled = true; 86 omap4_i2c_reg_write(dev, OMAP4_I2C_IRQENABLE_SET, IRQENABLE_XDR | IRQENABLE_RDR | 87 IRQENABLE_XRDY | IRQENABLE_RRDY | IRQENABLE_ARDY | IRQENABLE_NACK); 88} 89 90static void omap4_i2c_disable_interrupts(omap4_i2c_dev_t *dev) 91{ 92 dev->interrupts_enabled = false; 93 omap4_i2c_reg_write(dev, OMAP4_I2C_IRQENABLE_CLR, IRQENABLE_XDR | IRQENABLE_RDR | 94 IRQENABLE_XRDY | IRQENABLE_RRDY | IRQENABLE_ARDY | IRQENABLE_NACK); 95} 96 97static void omap4_i2c_wait_for_bb(i2c_bus_t *bus) 98{ 99 omap4_i2c_dev_t *dev = bus->priv; 100 while (omap4_i2c_reg_read(dev, OMAP4_I2C_IRQSTATUS_RAW) & IRQSTATUS_BB); 101} 102 103static int omap4_i2c_controller_init(i2c_bus_t *bus) 104{ 105 omap4_i2c_dev_t *dev = bus->priv; 106 107 /* set prescaler and SCL timings */ 108 int internal_clock; 109 uint16_t scll, sclh; 110 uint16_t prescale; 111 112 /* these values are taken from Table 23-9, OMAP4460 Technical Reference Manual, version AB */ 113 switch (dev->speed) { 114 case I2C_SLAVE_SPEED_STANDARD: 115 internal_clock = 4000000; 116 scll = 13; 117 sclh = 15; 118 break; 119 case I2C_SLAVE_SPEED_FAST: 120 internal_clock = 9600000; 121 scll = 7; 122 sclh = 5; 123 break; 124 default: 125 ZF_LOGE("Unsupported I2C speed!"); 126 return -1; 127 } 128 129 prescale = AM335X_I2C_SCLK / internal_clock - 1; 130 131 /* disable I2C module for reconfiguration */ 132 omap4_i2c_reg_write(dev, OMAP4_I2C_CON, 0); 133 134 /* write clock configuration */ 135 omap4_i2c_reg_write(dev, OMAP4_I2C_PSC, prescale); 136 omap4_i2c_reg_write(dev, OMAP4_I2C_SCLL, scll); 137 omap4_i2c_reg_write(dev, OMAP4_I2C_SCLH, sclh); 138 139 /* clamp FIFO depth to maximum possible size */ 140 dev->fifo_threshold = MIN(dev->fifo_threshold, AM335X_I2C_MAX_FIFODEPTH); 141 /* configure FIFO */ 142 uint16_t buf_reg = ((dev->fifo_threshold - 1) << BUF_RXTRSH_OFFSET) & BUF_RXTRSH_MASK; 143 buf_reg |= (dev->fifo_threshold - 1) & BUF_TXTRSH_MASK; 144 omap4_i2c_reg_write(dev, OMAP4_I2C_BUF, buf_reg); 145 146 /* enable module */ 147 omap4_i2c_reg_write(dev, OMAP4_I2C_CON, CON_I2C_EN); 148 149 return 0; 150} 151 152static int omap4_i2c_do_xfer(i2c_slave_t *slave, void *data, size_t size, bool write, 153 bool repeat_start, i2c_callback_fn cb, void *token) 154{ 155 ZF_LOGV("%s %zu bytes from slave 0x%x", write ? "writing" : "reading", size, slave->address); 156 i2c_bus_t *bus = slave->bus; 157 omap4_i2c_dev_t *dev = bus->priv; 158 159 if (dev->busy) { 160 ZF_LOGE("i2c bus is busy "); 161 return -1; 162 } 163 164 if (size == 0) { 165 cb(bus, I2CSTAT_COMPLETE, size, token); 166 return 0; 167 } 168 169 /* skip polling for bus-busy if the device is in repeat-start mode */ 170 if (!dev->repeat_start) { 171 omap4_i2c_wait_for_bb(bus); 172 } 173 174 if (slave->max_speed < dev->speed) { 175 uint32_t freq = i2c_set_speed(bus, slave->max_speed); 176 if (freq != i2c_speed_freqs[slave->max_speed]) { 177 ZF_LOGE("failed to set speed"); 178 return -1; 179 } 180 } 181 182 omap4_i2c_reg_write(dev, OMAP4_I2C_SA, slave->address); 183 184 if (write) { 185 dev->mode = I2CMODE_TX; 186 } else { 187 dev->mode = I2CMODE_RX; 188 } 189 dev->buf = data; 190 dev->buf_len = size; 191 dev->buf_pos = 0; 192 dev->repeat_start = repeat_start; 193 dev->status = I2CSTAT_COMPLETE; 194 195 omap4_i2c_reg_write(dev, OMAP4_I2C_CNT, size); 196 197 /* clear FIFO */ 198 uint16_t buf_reg = omap4_i2c_reg_read(dev, OMAP4_I2C_BUF); 199 buf_reg |= BUF_RXFIFO_CLR | BUF_TXFIFO_CLR; 200 omap4_i2c_reg_write(dev, OMAP4_I2C_BUF, buf_reg); 201 202 uint16_t con_reg = CON_I2C_EN | CON_MST | CON_STT; 203 if (!repeat_start) { 204 con_reg |= CON_STP; 205 } 206 if (write) { 207 con_reg |= CON_TRX; 208 } 209 210 omap4_i2c_reg_write(dev, OMAP4_I2C_CON, con_reg); 211 212 dev->busy = true; 213 if (cb == NULL) { 214 /* synchronous */ 215 while (dev->busy) { 216 i2c_handle_irq(bus); 217 } 218 return dev->buf_pos; 219 } else { 220 /* asynchronous */ 221 bus->cb = cb; 222 bus->token = token; 223 224 omap4_i2c_enable_interrupts(dev); 225 return size; 226 } 227 return 0; 228} 229 230static int omap4_i2c_slave_read(i2c_slave_t *slave, void *data, size_t size, 231 bool repeat_start, i2c_callback_fn cb, void *token) 232{ 233 return omap4_i2c_do_xfer(slave, data, size, false, repeat_start, cb, token); 234} 235 236static int omap4_i2c_slave_write(i2c_slave_t *slave, const void *data, size_t size, 237 bool repeat_start, i2c_callback_fn cb, void *token) 238{ 239 return omap4_i2c_do_xfer(slave, (void *) data, size, true, repeat_start, cb, token); 240} 241 242static int omap4_i2c_slave_init(i2c_bus_t *bus, int address, enum i2c_slave_address_size address_size, 243 enum i2c_slave_speed max_speed, uint32_t i2c_opts, i2c_slave_t *i2c_slave) 244{ 245 assert(i2c_slave != NULL); 246 247 if (address_size == I2C_SLAVE_ADDR_7BIT) { 248 address = i2c_extract_address(address); 249 } 250 251 *i2c_slave = (i2c_slave_t) { 252 .address = address, 253 .address_size = address_size, 254 .max_speed = max_speed, 255 .i2c_opts = i2c_opts, 256 .bus = bus, 257 258 .slave_read = &omap4_i2c_slave_read, 259 .slave_write = &omap4_i2c_slave_write 260 }; 261 262 return 0; 263} 264 265static long omap4_i2c_set_speed(i2c_bus_t *bus, enum i2c_slave_speed speed) 266{ 267 omap4_i2c_dev_t *dev = bus->priv; 268 dev->speed = speed; 269 270 omap4_i2c_wait_for_bb(bus); 271 int err = omap4_i2c_controller_init(bus); 272 if (err) { 273 return err; 274 } 275 276 return i2c_speed_freqs[speed]; 277} 278 279static int omap4_i2c_master_stop(i2c_bus_t *bus) 280{ 281 omap4_i2c_dev_t *dev = bus->priv; 282 283 uint16_t con_reg = omap4_i2c_reg_read(dev, OMAP4_I2C_CON); 284 con_reg |= CON_STP; 285 omap4_i2c_reg_write(dev, OMAP4_I2C_CON, con_reg); 286 287 omap4_i2c_wait_for_bb(bus); 288 289 omap4_i2c_reg_write(dev, OMAP4_I2C_CON, 0); 290 return 0; 291} 292 293static void omap4_i2c_handle_irq(i2c_bus_t *bus) 294{ 295 omap4_i2c_dev_t *dev = bus->priv; 296 size_t bytes = 0; 297 298 uint16_t irq_status = omap4_i2c_reg_read(dev, OMAP4_I2C_IRQSTATUS_RAW); 299 if (dev->interrupts_enabled) { 300 uint16_t irq_enabled = omap4_i2c_reg_read(dev, OMAP4_I2C_IRQENABLE_SET); 301 302 /* mask disabled interrupts */ 303 irq_status &= irq_enabled; 304 } 305 306 ZF_LOGV("IRQSTATUS = 0x%x", irq_status); 307 308 if (irq_status & IRQSTATUS_NACK) { 309 /* NACK from slave */ 310 ZF_LOGV("NACK"); 311 dev->status = I2CSTAT_NACK; 312 omap4_i2c_reg_write(dev, OMAP4_I2C_IRQSTATUS, IRQSTATUS_NACK); 313 } 314 315 if (irq_status & IRQSTATUS_ARDY) { 316 /* transfer complete */ 317 ZF_LOGV("ARDY"); 318 319 omap4_i2c_reg_write(dev, OMAP4_I2C_IRQSTATUS, IRQSTATUS_ARDY | IRQSTATUS_RRDY | IRQSTATUS_XRDY | 320 IRQSTATUS_RDR | IRQSTATUS_XDR); 321 322 /* run callback */ 323 dev->mode = I2CMODE_IDLE; 324 dev->busy = false; 325 if (bus->cb) { 326 bus->cb(bus, dev->status, dev->buf_pos, bus->token); 327 bus->cb = NULL; 328 bus->token = NULL; 329 } 330 331 if (dev->interrupts_enabled) { 332 omap4_i2c_disable_interrupts(dev); 333 } 334 335 return; 336 } 337 338 if (dev->mode == I2CMODE_RX) { 339 if (irq_status & IRQSTATUS_RDR) { 340 /* receive drain */ 341 ZF_LOGV("RDR"); 342 bytes = dev->buf_len - dev->buf_pos; 343 } else if (irq_status & IRQSTATUS_RRDY) { 344 /* receive ready */ 345 ZF_LOGV("RRDY"); 346 bytes = MIN(dev->fifo_threshold, dev->buf_len - dev->buf_pos); 347 } 348 349 for (size_t i = 0; i < bytes; i++) { 350 dev->buf[dev->buf_pos] = omap4_i2c_reg_read(dev, OMAP4_I2C_DATA); 351 dev->buf_pos++; 352 } 353 354 if (irq_status & IRQSTATUS_RDR) { 355 omap4_i2c_reg_write(dev, OMAP4_I2C_IRQSTATUS, IRQSTATUS_RDR); 356 } 357 if (irq_status & IRQSTATUS_RRDY) { 358 omap4_i2c_reg_write(dev, OMAP4_I2C_IRQSTATUS, IRQSTATUS_RRDY); 359 } 360 } 361 362 if (dev->mode == I2CMODE_TX) { 363 if (irq_status & IRQSTATUS_XDR) { 364 /* transmit drain */ 365 ZF_LOGV("XDR"); 366 bytes = dev->buf_len - dev->buf_pos; 367 } else if (irq_status & IRQSTATUS_XRDY) { 368 /* transmit ready */ 369 ZF_LOGV("XRDY"); 370 bytes = MIN(dev->fifo_threshold, dev->buf_len - dev->buf_pos); 371 } 372 373 for (size_t i = 0; i < bytes; i++) { 374 omap4_i2c_reg_write(dev, OMAP4_I2C_DATA, dev->buf[dev->buf_pos]); 375 dev->buf_pos++; 376 } 377 378 if (irq_status & IRQSTATUS_XDR) { 379 omap4_i2c_reg_write(dev, OMAP4_I2C_IRQSTATUS, IRQSTATUS_XDR); 380 } 381 if (irq_status & IRQSTATUS_XRDY) { 382 omap4_i2c_reg_write(dev, OMAP4_I2C_IRQSTATUS, IRQSTATUS_XRDY); 383 } 384 } 385} 386 387int omap4_i2c_init(void *vaddr, int irq_id, ps_io_ops_t *io_ops, i2c_bus_t *i2c_bus) 388{ 389 struct omap4_i2c_dev *dev; 390 391 int error = ps_malloc(&io_ops->malloc_ops, sizeof(omap4_i2c_dev_t), (void **) &dev); 392 if (error) { 393 ZF_LOGE("Failed to allocate device"); 394 return -1; 395 } 396 397 *dev = (omap4_i2c_dev_t) { 398 .regs = vaddr, 399 .irq_id = irq_id, 400 .speed = I2C_SLAVE_SPEED_FAST, 401 .fifo_threshold = AM335X_I2C_MAX_FIFODEPTH - 1 402 }; 403 *i2c_bus = (i2c_bus_t) { 404 .slave_init = omap4_i2c_slave_init, 405 .set_speed = omap4_i2c_set_speed, 406 .master_stop = omap4_i2c_master_stop, 407 .handle_irq = omap4_i2c_handle_irq, 408 .priv = dev 409 }; 410 411 error = omap4_i2c_controller_init(i2c_bus); 412 if (error) { 413 ZF_LOGE("Failed to initialise I2C controller"); 414 ps_free(&io_ops->malloc_ops, sizeof(omap4_i2c_dev_t), dev); 415 i2c_bus->priv = NULL; 416 return -1; 417 } 418 419 return 0; 420} 421 422int i2c_init(enum i2c_id id, ps_io_ops_t *io_ops, i2c_bus_t *i2c_bus) 423{ 424 void *vaddr; 425 int irq_id; 426 427 assert(io_ops != NULL); 428 assert(i2c_bus != NULL); 429 430 switch (id) { 431 case AM335X_I2C0: 432 case AM335X_I2C1: 433 case AM335X_I2C2: 434 vaddr = ps_pmem_map(io_ops, pmems[id], false, PS_MEM_NORMAL); 435 if (vaddr == NULL) { 436 ZF_LOGE("Failed to map I2C controller %d", id); 437 return -1; 438 } 439 440 irq_id = ps_irq_register(&io_ops->irq_ops, irqs[id], i2c_handle_irq_wrapper, i2c_bus); 441 if (irq_id < 0) { 442 ZF_LOGE("Failed to register IRQ handler for I2C controller %d", id); 443 ps_pmem_unmap(io_ops, pmems[id], vaddr); 444 return -1; 445 } 446 447 break; 448 default: 449 ZF_LOGE("Unknown I2C controller %d", id); 450 return -1; 451 } 452 453 return omap4_i2c_init(vaddr, irq_id, io_ops, i2c_bus); 454} 455