1239281Sgonzo/*- 2239281Sgonzo * Copyright (c) 2011 3239281Sgonzo * Ben Gray <ben.r.gray@gmail.com>. 4239281Sgonzo * All rights reserved. 5239281Sgonzo * 6239281Sgonzo * Redistribution and use in source and binary forms, with or without 7239281Sgonzo * modification, are permitted provided that the following conditions 8239281Sgonzo * are met: 9239281Sgonzo * 1. Redistributions of source code must retain the above copyright 10239281Sgonzo * notice, this list of conditions and the following disclaimer. 11239281Sgonzo * 2. Redistributions in binary form must reproduce the above copyright 12239281Sgonzo * notice, this list of conditions and the following disclaimer in the 13239281Sgonzo * documentation and/or other materials provided with the distribution. 14239281Sgonzo * 15239281Sgonzo * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16239281Sgonzo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17239281Sgonzo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18239281Sgonzo * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 19239281Sgonzo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20239281Sgonzo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21239281Sgonzo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22239281Sgonzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23239281Sgonzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24239281Sgonzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25239281Sgonzo * SUCH DAMAGE. 26239281Sgonzo */ 27239281Sgonzo 28239281Sgonzo/** 29239281Sgonzo * Driver for the I2C module on the TI SoC. 30239281Sgonzo * 31239281Sgonzo * This driver is heavily based on the TWI driver for the AT91 (at91_twi.c). 32239281Sgonzo * 33239281Sgonzo * CAUTION: The I2Ci registers are limited to 16 bit and 8 bit data accesses, 34239281Sgonzo * 32 bit data access is not allowed and can corrupt register content. 35239281Sgonzo * 36239281Sgonzo * This driver currently doesn't use DMA for the transfer, although I hope to 37239281Sgonzo * incorporate that sometime in the future. The idea being that for transaction 38239281Sgonzo * larger than a certain size the DMA engine is used, for anything less the 39239281Sgonzo * normal interrupt/fifo driven option is used. 40239281Sgonzo * 41239281Sgonzo * 42239281Sgonzo * WARNING: This driver uses mtx_sleep and interrupts to perform transactions, 43239281Sgonzo * which means you can't do a transaction during startup before the interrupts 44239281Sgonzo * have been enabled. Hint - the freebsd function config_intrhook_establish(). 45239281Sgonzo */ 46239281Sgonzo 47239281Sgonzo#include <sys/cdefs.h> 48239281Sgonzo__FBSDID("$FreeBSD$"); 49239281Sgonzo 50239281Sgonzo#include <sys/param.h> 51239281Sgonzo#include <sys/systm.h> 52239281Sgonzo#include <sys/bus.h> 53239281Sgonzo#include <sys/conf.h> 54239281Sgonzo#include <sys/kernel.h> 55239281Sgonzo#include <sys/lock.h> 56239281Sgonzo#include <sys/mbuf.h> 57239281Sgonzo#include <sys/malloc.h> 58239281Sgonzo#include <sys/module.h> 59239281Sgonzo#include <sys/mutex.h> 60239281Sgonzo#include <sys/rman.h> 61239281Sgonzo#include <machine/bus.h> 62239281Sgonzo 63239281Sgonzo#include <dev/fdt/fdt_common.h> 64239281Sgonzo#include <dev/ofw/openfirm.h> 65239281Sgonzo#include <dev/ofw/ofw_bus.h> 66239281Sgonzo#include <dev/ofw/ofw_bus_subr.h> 67239281Sgonzo 68239281Sgonzo#include <arm/ti/ti_prcm.h> 69239281Sgonzo#include <arm/ti/ti_i2c.h> 70239281Sgonzo 71239281Sgonzo#include <dev/iicbus/iiconf.h> 72239281Sgonzo#include <dev/iicbus/iicbus.h> 73239281Sgonzo 74239281Sgonzo#include "iicbus_if.h" 75239281Sgonzo 76239281Sgonzo/** 77239281Sgonzo * I2C device driver context, a pointer to this is stored in the device 78239281Sgonzo * driver structure. 79239281Sgonzo */ 80239281Sgonzostruct ti_i2c_softc 81239281Sgonzo{ 82239281Sgonzo device_t sc_dev; 83239281Sgonzo uint32_t device_id; 84239281Sgonzo struct resource* sc_irq_res; 85239281Sgonzo struct resource* sc_mem_res; 86239281Sgonzo device_t sc_iicbus; 87239281Sgonzo 88239281Sgonzo void* sc_irq_h; 89239281Sgonzo 90239281Sgonzo struct mtx sc_mtx; 91239281Sgonzo 92239281Sgonzo volatile uint16_t sc_stat_flags; /* contains the status flags last IRQ */ 93239281Sgonzo 94239281Sgonzo uint16_t sc_i2c_addr; 95239281Sgonzo uint16_t sc_rev; 96239281Sgonzo}; 97239281Sgonzo 98239281Sgonzostruct ti_i2c_clock_config 99239281Sgonzo{ 100239281Sgonzo int speed; 101239281Sgonzo int bitrate; 102239281Sgonzo uint8_t psc; /* Fast/Standard mode prescale divider */ 103239281Sgonzo uint8_t scll; /* Fast/Standard mode SCL low time */ 104239281Sgonzo uint8_t sclh; /* Fast/Standard mode SCL high time */ 105239281Sgonzo uint8_t hsscll; /* High Speed mode SCL low time */ 106239281Sgonzo uint8_t hssclh; /* High Speed mode SCL high time */ 107239281Sgonzo}; 108239281Sgonzo 109239281Sgonzostatic struct ti_i2c_clock_config ti_i2c_clock_configs[] = { 110239281Sgonzo 111239281Sgonzo#if defined(SOC_OMAP4) 112239281Sgonzo { IIC_SLOW, 100000, 23, 13, 15, 0, 0}, 113239281Sgonzo { IIC_FAST, 400000, 9, 5, 7, 0, 0}, 114239281Sgonzo { IIC_FASTEST, 3310000, 1, 113, 115, 7, 10}, 115239281Sgonzo#elif defined(SOC_TI_AM335X) 116239281Sgonzo { IIC_SLOW, 100000, 3, 53, 55, 0, 0}, 117239281Sgonzo { IIC_FAST, 400000, 3, 8, 10, 0, 0}, 118239281Sgonzo { IIC_FASTEST, 400000, 3, 8, 10, 0, 0}, /* This might be higher */ 119239281Sgonzo#else 120239281Sgonzo#error "TI I2C driver is not supported on this SoC" 121239281Sgonzo#endif 122239281Sgonzo { -1, 0 } 123239281Sgonzo}; 124239281Sgonzo 125239281Sgonzo 126239281Sgonzo#define TI_I2C_REV1 0x003C /* OMAP3 */ 127239281Sgonzo#define TI_I2C_REV2 0x000A /* OMAP4 */ 128239281Sgonzo 129239281Sgonzo/** 130239281Sgonzo * Locking macros used throughout the driver 131239281Sgonzo */ 132239281Sgonzo#define TI_I2C_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 133239281Sgonzo#define TI_I2C_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 134239281Sgonzo#define TI_I2C_LOCK_INIT(_sc) \ 135239281Sgonzo mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \ 136239281Sgonzo "ti_i2c", MTX_DEF) 137239281Sgonzo#define TI_I2C_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 138239281Sgonzo#define TI_I2C_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); 139239281Sgonzo#define TI_I2C_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); 140239281Sgonzo 141239281Sgonzo#ifdef DEBUG 142239281Sgonzo#define ti_i2c_dbg(_sc, fmt, args...) \ 143239281Sgonzo device_printf((_sc)->sc_dev, fmt, ##args) 144239281Sgonzo#else 145239281Sgonzo#define ti_i2c_dbg(_sc, fmt, args...) 146239281Sgonzo#endif 147239281Sgonzo 148239281Sgonzostatic devclass_t ti_i2c_devclass; 149239281Sgonzo 150239281Sgonzo/* bus entry points */ 151239281Sgonzo 152239281Sgonzostatic int ti_i2c_probe(device_t dev); 153239281Sgonzostatic int ti_i2c_attach(device_t dev); 154239281Sgonzostatic int ti_i2c_detach(device_t dev); 155239281Sgonzostatic void ti_i2c_intr(void *); 156239281Sgonzo 157239281Sgonzo/* OFW routine */ 158239281Sgonzostatic phandle_t ti_i2c_get_node(device_t bus, device_t dev); 159239281Sgonzo 160239281Sgonzo/* helper routines */ 161239281Sgonzostatic int ti_i2c_activate(device_t dev); 162239281Sgonzostatic void ti_i2c_deactivate(device_t dev); 163239281Sgonzo 164239281Sgonzo/** 165239281Sgonzo * ti_i2c_read_2 - reads a 16-bit value from one of the I2C registers 166239281Sgonzo * @sc: I2C device context 167239281Sgonzo * @off: the byte offset within the register bank to read from. 168239281Sgonzo * 169239281Sgonzo * 170239281Sgonzo * LOCKING: 171239281Sgonzo * No locking required 172239281Sgonzo * 173239281Sgonzo * RETURNS: 174239281Sgonzo * 16-bit value read from the register. 175239281Sgonzo */ 176239281Sgonzostatic inline uint16_t 177239281Sgonzoti_i2c_read_2(struct ti_i2c_softc *sc, bus_size_t off) 178239281Sgonzo{ 179239281Sgonzo return bus_read_2(sc->sc_mem_res, off); 180239281Sgonzo} 181239281Sgonzo 182239281Sgonzo/** 183239281Sgonzo * ti_i2c_write_2 - writes a 16-bit value to one of the I2C registers 184239281Sgonzo * @sc: I2C device context 185239281Sgonzo * @off: the byte offset within the register bank to read from. 186239281Sgonzo * @val: the value to write into the register 187239281Sgonzo * 188239281Sgonzo * LOCKING: 189239281Sgonzo * No locking required 190239281Sgonzo * 191239281Sgonzo * RETURNS: 192239281Sgonzo * 16-bit value read from the register. 193239281Sgonzo */ 194239281Sgonzostatic inline void 195239281Sgonzoti_i2c_write_2(struct ti_i2c_softc *sc, bus_size_t off, uint16_t val) 196239281Sgonzo{ 197239281Sgonzo bus_write_2(sc->sc_mem_res, off, val); 198239281Sgonzo} 199239281Sgonzo 200239281Sgonzo/** 201239281Sgonzo * ti_i2c_read_reg - reads a 16-bit value from one of the I2C registers 202239281Sgonzo * take into account revision-dependent register offset 203239281Sgonzo * @sc: I2C device context 204239281Sgonzo * @off: the byte offset within the register bank to read from. 205239281Sgonzo * 206239281Sgonzo * 207239281Sgonzo * LOCKING: 208239281Sgonzo * No locking required 209239281Sgonzo * 210239281Sgonzo * RETURNS: 211239281Sgonzo * 16-bit value read from the register. 212239281Sgonzo */ 213239281Sgonzostatic inline uint16_t 214239281Sgonzoti_i2c_read_reg(struct ti_i2c_softc *sc, bus_size_t off) 215239281Sgonzo{ 216239281Sgonzo /* XXXOMAP3: FIXME add registers mapping here */ 217239281Sgonzo return bus_read_2(sc->sc_mem_res, off); 218239281Sgonzo} 219239281Sgonzo 220239281Sgonzo/** 221239281Sgonzo * ti_i2c_write_reg - writes a 16-bit value to one of the I2C registers 222239281Sgonzo * take into account revision-dependent register offset 223239281Sgonzo * @sc: I2C device context 224239281Sgonzo * @off: the byte offset within the register bank to read from. 225239281Sgonzo * @val: the value to write into the register 226239281Sgonzo * 227239281Sgonzo * LOCKING: 228239281Sgonzo * No locking required 229239281Sgonzo * 230239281Sgonzo * RETURNS: 231239281Sgonzo * 16-bit value read from the register. 232239281Sgonzo */ 233239281Sgonzostatic inline void 234239281Sgonzoti_i2c_write_reg(struct ti_i2c_softc *sc, bus_size_t off, uint16_t val) 235239281Sgonzo{ 236239281Sgonzo /* XXXOMAP3: FIXME add registers mapping here */ 237239281Sgonzo bus_write_2(sc->sc_mem_res, off, val); 238239281Sgonzo} 239239281Sgonzo 240239281Sgonzo/** 241239281Sgonzo * ti_i2c_set_intr_enable - writes the interrupt enable register 242239281Sgonzo * @sc: I2C device context 243239281Sgonzo * @ie: bitmask of the interrupts to enable 244239281Sgonzo * 245239281Sgonzo * This function is needed as writing the I2C_IE register on the OMAP4 devices 246239281Sgonzo * doesn't seem to actually enable the interrupt, rather you have to write 247239281Sgonzo * through the I2C_IRQENABLE_CLR and I2C_IRQENABLE_SET registers. 248239281Sgonzo * 249239281Sgonzo * LOCKING: 250239281Sgonzo * No locking required 251239281Sgonzo * 252239281Sgonzo * RETURNS: 253239281Sgonzo * Nothing. 254239281Sgonzo */ 255239281Sgonzostatic inline void 256239281Sgonzoti_i2c_set_intr_enable(struct ti_i2c_softc *sc, uint16_t ie) 257239281Sgonzo{ 258239281Sgonzo /* XXXOMAP3: FIXME */ 259239281Sgonzo ti_i2c_write_2(sc, I2C_REG_IRQENABLE_CLR, 0xffff); 260239281Sgonzo if (ie) 261239281Sgonzo ti_i2c_write_2(sc, I2C_REG_IRQENABLE_SET, ie); 262239281Sgonzo} 263239281Sgonzo 264239281Sgonzo/** 265239281Sgonzo * ti_i2c_reset - attach function for the driver 266239281Sgonzo * @dev: i2c device handle 267239281Sgonzo * 268239281Sgonzo * 269239281Sgonzo * 270239281Sgonzo * LOCKING: 271239281Sgonzo * Called from timer context 272239281Sgonzo * 273239281Sgonzo * RETURNS: 274239281Sgonzo * EH_HANDLED or EH_NOT_HANDLED 275239281Sgonzo */ 276239281Sgonzostatic int 277239281Sgonzoti_i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 278239281Sgonzo{ 279239281Sgonzo struct ti_i2c_softc *sc = device_get_softc(dev); 280239281Sgonzo struct ti_i2c_clock_config *clkcfg; 281239281Sgonzo uint16_t con_reg; 282239281Sgonzo 283239281Sgonzo clkcfg = ti_i2c_clock_configs; 284239281Sgonzo while (clkcfg->speed != -1) { 285239281Sgonzo if (clkcfg->speed == speed) 286239281Sgonzo break; 287239281Sgonzo /* take slow if speed is unknown */ 288239281Sgonzo if ((speed == IIC_UNKNOWN) && (clkcfg->speed == IIC_SLOW)) 289239281Sgonzo break; 290239281Sgonzo clkcfg++; 291239281Sgonzo } 292239281Sgonzo if (clkcfg->speed == -1) 293239281Sgonzo return (EINVAL); 294239281Sgonzo 295239281Sgonzo TI_I2C_LOCK(sc); 296239281Sgonzo 297239281Sgonzo if (oldaddr) 298239281Sgonzo *oldaddr = sc->sc_i2c_addr; 299239281Sgonzo sc->sc_i2c_addr = addr; 300239281Sgonzo 301239281Sgonzo /* First disable the controller while changing the clocks */ 302239281Sgonzo con_reg = ti_i2c_read_reg(sc, I2C_REG_CON); 303239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, 0x0000); 304239281Sgonzo 305239281Sgonzo /* Program the prescaler */ 306239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_PSC, clkcfg->psc); 307239281Sgonzo 308239281Sgonzo /* Set the bitrate */ 309239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_SCLL, clkcfg->scll | (clkcfg->hsscll<<8)); 310239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_SCLH, clkcfg->sclh | (clkcfg->hssclh<<8)); 311239281Sgonzo 312239281Sgonzo /* Set the remote slave address */ 313239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_SA, addr); 314239281Sgonzo 315239281Sgonzo /* Check if we are dealing with high speed mode */ 316239281Sgonzo if ((clkcfg->hsscll + clkcfg->hssclh) > 0) 317239281Sgonzo con_reg = I2C_CON_OPMODE_HS; 318239281Sgonzo else 319239281Sgonzo con_reg = I2C_CON_OPMODE_STD; 320239281Sgonzo 321239281Sgonzo /* Enable the I2C module again */ 322239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, I2C_CON_I2C_EN | con_reg); 323239281Sgonzo 324239281Sgonzo TI_I2C_UNLOCK(sc); 325239281Sgonzo 326239281Sgonzo return 0; 327239281Sgonzo} 328239281Sgonzo 329239281Sgonzo/** 330239281Sgonzo * ti_i2c_intr - interrupt handler for the I2C module 331239281Sgonzo * @dev: i2c device handle 332239281Sgonzo * 333239281Sgonzo * 334239281Sgonzo * 335239281Sgonzo * LOCKING: 336239281Sgonzo * Called from timer context 337239281Sgonzo * 338239281Sgonzo * RETURNS: 339239281Sgonzo * EH_HANDLED or EH_NOT_HANDLED 340239281Sgonzo */ 341239281Sgonzostatic void 342239281Sgonzoti_i2c_intr(void *arg) 343239281Sgonzo{ 344239281Sgonzo struct ti_i2c_softc *sc = (struct ti_i2c_softc*) arg; 345239281Sgonzo uint16_t status; 346239281Sgonzo 347239281Sgonzo status = ti_i2c_read_reg(sc, I2C_REG_STAT); 348239281Sgonzo if (status == 0) 349239281Sgonzo return; 350239281Sgonzo 351239281Sgonzo TI_I2C_LOCK(sc); 352239281Sgonzo 353239281Sgonzo /* save the flags */ 354239281Sgonzo sc->sc_stat_flags |= status; 355239281Sgonzo 356239281Sgonzo /* clear the status flags */ 357239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_STAT, status); 358239281Sgonzo 359239281Sgonzo /* wakeup the process the started the transaction */ 360239281Sgonzo wakeup(sc); 361239281Sgonzo 362239281Sgonzo TI_I2C_UNLOCK(sc); 363239281Sgonzo 364239281Sgonzo return; 365239281Sgonzo} 366239281Sgonzo 367239281Sgonzo/** 368239281Sgonzo * ti_i2c_wait - waits for the specific event to occur 369239281Sgonzo * @sc: i2c driver context 370239281Sgonzo * @flags: the event(s) to wait on, this is a bitmask of the I2C_STAT_??? flags 371239281Sgonzo * @statp: if not null will contain the status flags upon return 372239281Sgonzo * @timo: the number of ticks to wait 373239281Sgonzo * 374239281Sgonzo * 375239281Sgonzo * 376239281Sgonzo * LOCKING: 377239281Sgonzo * The driver context must be locked before calling this function. Internally 378239281Sgonzo * the function sleeps, releasing the lock as it does so, however the lock is 379239281Sgonzo * always retaken before this function returns. 380239281Sgonzo * 381239281Sgonzo * RETURNS: 382239281Sgonzo * 0 if the event(s) were tripped within timeout period 383239281Sgonzo * EBUSY if timedout waiting for the events 384239281Sgonzo * ENXIO if a NACK event was received 385239281Sgonzo */ 386239281Sgonzostatic int 387239281Sgonzoti_i2c_wait(struct ti_i2c_softc *sc, uint16_t flags, uint16_t *statp, int timo) 388239281Sgonzo{ 389239281Sgonzo int waittime = timo; 390239281Sgonzo int start_ticks = ticks; 391239281Sgonzo int rc; 392239281Sgonzo 393239281Sgonzo TI_I2C_ASSERT_LOCKED(sc); 394239281Sgonzo 395239281Sgonzo /* check if the condition has already occured, the interrupt routine will 396239281Sgonzo * clear the status flags. 397239281Sgonzo */ 398239281Sgonzo if ((sc->sc_stat_flags & flags) == 0) { 399239281Sgonzo 400239281Sgonzo /* condition(s) haven't occured so sleep on the IRQ */ 401239281Sgonzo while (waittime > 0) { 402239281Sgonzo 403239281Sgonzo rc = mtx_sleep(sc, &sc->sc_mtx, 0, "I2Cwait", waittime); 404239281Sgonzo if (rc == EWOULDBLOCK) { 405239281Sgonzo /* timed-out, simply break out of the loop */ 406239281Sgonzo break; 407239281Sgonzo } else { 408239281Sgonzo /* IRQ has been tripped, but need to sanity check we have the 409239281Sgonzo * right events in the status flag. 410239281Sgonzo */ 411239281Sgonzo if ((sc->sc_stat_flags & flags) != 0) 412239281Sgonzo break; 413239281Sgonzo 414239281Sgonzo /* event hasn't been tripped so wait some more */ 415239281Sgonzo waittime -= (ticks - start_ticks); 416239281Sgonzo start_ticks = ticks; 417239281Sgonzo } 418239281Sgonzo } 419239281Sgonzo } 420239281Sgonzo 421239281Sgonzo /* copy the actual status bits */ 422239281Sgonzo if (statp != NULL) 423239281Sgonzo *statp = sc->sc_stat_flags; 424239281Sgonzo 425239281Sgonzo /* return the status found */ 426239281Sgonzo if ((sc->sc_stat_flags & flags) != 0) 427239281Sgonzo rc = 0; 428239281Sgonzo else 429239281Sgonzo rc = EBUSY; 430239281Sgonzo 431239281Sgonzo /* clear the flags set by the interrupt handler */ 432239281Sgonzo sc->sc_stat_flags = 0; 433239281Sgonzo 434239281Sgonzo return (rc); 435239281Sgonzo} 436239281Sgonzo 437239281Sgonzo/** 438239281Sgonzo * ti_i2c_wait_for_free_bus - waits for the bus to become free 439239281Sgonzo * @sc: i2c driver context 440239281Sgonzo * @timo: the time to wait for the bus to become free 441239281Sgonzo * 442239281Sgonzo * 443239281Sgonzo * 444239281Sgonzo * LOCKING: 445239281Sgonzo * The driver context must be locked before calling this function. Internally 446239281Sgonzo * the function sleeps, releasing the lock as it does so, however the lock is 447239281Sgonzo * always taken before this function returns. 448239281Sgonzo * 449239281Sgonzo * RETURNS: 450239281Sgonzo * 0 if the event(s) were tripped within timeout period 451239281Sgonzo * EBUSY if timedout waiting for the events 452239281Sgonzo * ENXIO if a NACK event was received 453239281Sgonzo */ 454239281Sgonzostatic int 455239281Sgonzoti_i2c_wait_for_free_bus(struct ti_i2c_softc *sc, int timo) 456239281Sgonzo{ 457239281Sgonzo /* check if the bus is free, BB bit = 0 */ 458239281Sgonzo if ((ti_i2c_read_reg(sc, I2C_REG_STAT) & I2C_STAT_BB) == 0) 459239281Sgonzo return 0; 460239281Sgonzo 461239281Sgonzo /* enable bus free interrupts */ 462239281Sgonzo ti_i2c_set_intr_enable(sc, I2C_IE_BF); 463239281Sgonzo 464239281Sgonzo /* wait for the bus free interrupt to be tripped */ 465239281Sgonzo return ti_i2c_wait(sc, I2C_STAT_BF, NULL, timo); 466239281Sgonzo} 467239281Sgonzo 468239281Sgonzo/** 469239281Sgonzo * ti_i2c_read_bytes - attempts to perform a read operation 470239281Sgonzo * @sc: i2c driver context 471239281Sgonzo * @buf: buffer to hold the received bytes 472239281Sgonzo * @len: the number of bytes to read 473239281Sgonzo * 474239281Sgonzo * This function assumes the slave address is already set 475239281Sgonzo * 476239281Sgonzo * LOCKING: 477239281Sgonzo * The context lock should be held before calling this function 478239281Sgonzo * 479239281Sgonzo * RETURNS: 480239281Sgonzo * 0 on function succeeded 481239281Sgonzo * EINVAL if invalid message is passed as an arg 482239281Sgonzo */ 483239281Sgonzostatic int 484239281Sgonzoti_i2c_read_bytes(struct ti_i2c_softc *sc, uint8_t *buf, uint16_t len) 485239281Sgonzo{ 486239281Sgonzo int timo = (hz / 4); 487239281Sgonzo int err = 0; 488239281Sgonzo uint16_t con_reg; 489239281Sgonzo uint16_t events; 490239281Sgonzo uint16_t status; 491239281Sgonzo uint32_t amount = 0; 492239281Sgonzo uint32_t sofar = 0; 493239281Sgonzo uint32_t i; 494239281Sgonzo 495239281Sgonzo /* wait for the bus to become free */ 496239281Sgonzo err = ti_i2c_wait_for_free_bus(sc, timo); 497239281Sgonzo if (err != 0) { 498239281Sgonzo device_printf(sc->sc_dev, "bus never freed\n"); 499239281Sgonzo return (err); 500239281Sgonzo } 501239281Sgonzo 502239281Sgonzo /* set the events to wait for */ 503239281Sgonzo events = I2C_IE_RDR | /* Receive draining interrupt */ 504239281Sgonzo I2C_IE_RRDY | /* Receive Data Ready interrupt */ 505239281Sgonzo I2C_IE_ARDY | /* Register Access Ready interrupt */ 506239281Sgonzo I2C_IE_NACK | /* No Acknowledgment interrupt */ 507239281Sgonzo I2C_IE_AL; 508239281Sgonzo 509239281Sgonzo /* enable interrupts for the events we want */ 510239281Sgonzo ti_i2c_set_intr_enable(sc, events); 511239281Sgonzo 512239281Sgonzo /* write the number of bytes to read */ 513239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CNT, len); 514239281Sgonzo 515239281Sgonzo /* clear the write bit and initiate the read transaction. Setting the STT 516239281Sgonzo * (start) bit initiates the transfer. 517239281Sgonzo */ 518239281Sgonzo con_reg = ti_i2c_read_reg(sc, I2C_REG_CON); 519239281Sgonzo con_reg &= ~I2C_CON_TRX; 520239281Sgonzo con_reg |= I2C_CON_MST | I2C_CON_STT | I2C_CON_STP; 521239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, con_reg); 522239281Sgonzo 523239281Sgonzo /* reading loop */ 524239281Sgonzo while (1) { 525239281Sgonzo 526239281Sgonzo /* wait for an event */ 527239281Sgonzo err = ti_i2c_wait(sc, events, &status, timo); 528239281Sgonzo if (err != 0) { 529239281Sgonzo break; 530239281Sgonzo } 531239281Sgonzo 532239281Sgonzo /* check for the error conditions */ 533239281Sgonzo if (status & I2C_STAT_NACK) { 534239281Sgonzo /* no ACK from slave */ 535239281Sgonzo ti_i2c_dbg(sc, "NACK\n"); 536239281Sgonzo err = ENXIO; 537239281Sgonzo break; 538239281Sgonzo } 539239281Sgonzo if (status & I2C_STAT_AL) { 540239281Sgonzo /* arbitration lost */ 541239281Sgonzo ti_i2c_dbg(sc, "Arbitration lost\n"); 542239281Sgonzo err = ENXIO; 543239281Sgonzo break; 544239281Sgonzo } 545239281Sgonzo 546239281Sgonzo /* check if we have finished */ 547239281Sgonzo if (status & I2C_STAT_ARDY) { 548239281Sgonzo /* register access ready - transaction complete basically */ 549239281Sgonzo ti_i2c_dbg(sc, "ARDY transaction complete\n"); 550239281Sgonzo err = 0; 551239281Sgonzo break; 552239281Sgonzo } 553239281Sgonzo 554239281Sgonzo /* read some data */ 555239281Sgonzo if (status & I2C_STAT_RDR) { 556239281Sgonzo /* Receive draining interrupt - last data received */ 557239281Sgonzo ti_i2c_dbg(sc, "Receive draining interrupt\n"); 558239281Sgonzo 559239281Sgonzo /* get the number of bytes in the FIFO */ 560239281Sgonzo amount = ti_i2c_read_reg(sc, I2C_REG_BUFSTAT); 561239281Sgonzo amount >>= 8; 562239281Sgonzo amount &= 0x3f; 563239281Sgonzo } 564239281Sgonzo else if (status & I2C_STAT_RRDY) { 565239281Sgonzo /* Receive data ready interrupt - enough data received */ 566239281Sgonzo ti_i2c_dbg(sc, "Receive data ready interrupt\n"); 567239281Sgonzo 568239281Sgonzo /* get the number of bytes in the FIFO */ 569239281Sgonzo amount = ti_i2c_read_reg(sc, I2C_REG_BUF); 570239281Sgonzo amount >>= 8; 571239281Sgonzo amount &= 0x3f; 572239281Sgonzo amount += 1; 573239281Sgonzo } 574239281Sgonzo 575239281Sgonzo /* sanity check we haven't overwritten the array */ 576239281Sgonzo if ((sofar + amount) > len) { 577239281Sgonzo ti_i2c_dbg(sc, "to many bytes to read\n"); 578239281Sgonzo amount = (len - sofar); 579239281Sgonzo } 580239281Sgonzo 581239281Sgonzo /* read the bytes from the fifo */ 582239281Sgonzo for (i = 0; i < amount; i++) { 583239281Sgonzo buf[sofar++] = (uint8_t)(ti_i2c_read_reg(sc, I2C_REG_DATA) & 0xff); 584239281Sgonzo } 585239281Sgonzo 586239281Sgonzo /* attempt to clear the receive ready bits */ 587239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_STAT, I2C_STAT_RDR | I2C_STAT_RRDY); 588239281Sgonzo } 589239281Sgonzo 590239281Sgonzo /* reset the registers regardless if there was an error or not */ 591239281Sgonzo ti_i2c_set_intr_enable(sc, 0x0000); 592239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, I2C_CON_I2C_EN | I2C_CON_MST | I2C_CON_STP); 593239281Sgonzo 594239281Sgonzo return (err); 595239281Sgonzo} 596239281Sgonzo 597239281Sgonzo/** 598239281Sgonzo * ti_i2c_write_bytes - attempts to perform a read operation 599239281Sgonzo * @sc: i2c driver context 600239281Sgonzo * @buf: buffer containing the bytes to write 601239281Sgonzo * @len: the number of bytes to write 602239281Sgonzo * 603239281Sgonzo * This function assumes the slave address is already set 604239281Sgonzo * 605239281Sgonzo * LOCKING: 606239281Sgonzo * The context lock should be held before calling this function 607239281Sgonzo * 608239281Sgonzo * RETURNS: 609239281Sgonzo * 0 on function succeeded 610239281Sgonzo * EINVAL if invalid message is passed as an arg 611239281Sgonzo */ 612239281Sgonzostatic int 613239281Sgonzoti_i2c_write_bytes(struct ti_i2c_softc *sc, const uint8_t *buf, uint16_t len) 614239281Sgonzo{ 615239281Sgonzo int timo = (hz / 4); 616239281Sgonzo int err = 0; 617239281Sgonzo uint16_t con_reg; 618239281Sgonzo uint16_t events; 619239281Sgonzo uint16_t status; 620239281Sgonzo uint32_t amount = 0; 621239281Sgonzo uint32_t sofar = 0; 622239281Sgonzo uint32_t i; 623239281Sgonzo 624239281Sgonzo /* wait for the bus to become free */ 625239281Sgonzo err = ti_i2c_wait_for_free_bus(sc, timo); 626239281Sgonzo if (err != 0) 627239281Sgonzo return (err); 628239281Sgonzo 629239281Sgonzo /* set the events to wait for */ 630239281Sgonzo events = I2C_IE_XDR | /* Transmit draining interrupt */ 631239281Sgonzo I2C_IE_XRDY | /* Transmit Data Ready interrupt */ 632239281Sgonzo I2C_IE_ARDY | /* Register Access Ready interrupt */ 633239281Sgonzo I2C_IE_NACK | /* No Acknowledgment interrupt */ 634239281Sgonzo I2C_IE_AL; 635239281Sgonzo 636239281Sgonzo /* enable interrupts for the events we want*/ 637239281Sgonzo ti_i2c_set_intr_enable(sc, events); 638239281Sgonzo 639239281Sgonzo /* write the number of bytes to write */ 640239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CNT, len); 641239281Sgonzo 642239281Sgonzo /* set the write bit and initiate the write transaction. Setting the STT 643239281Sgonzo * (start) bit initiates the transfer. 644239281Sgonzo */ 645239281Sgonzo con_reg = ti_i2c_read_reg(sc, I2C_REG_CON); 646239281Sgonzo con_reg |= I2C_CON_TRX | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP; 647239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, con_reg); 648239281Sgonzo 649239281Sgonzo /* writing loop */ 650239281Sgonzo while (1) { 651239281Sgonzo 652239281Sgonzo /* wait for an event */ 653239281Sgonzo err = ti_i2c_wait(sc, events, &status, timo); 654239281Sgonzo if (err != 0) { 655239281Sgonzo break; 656239281Sgonzo } 657239281Sgonzo 658239281Sgonzo /* check for the error conditions */ 659239281Sgonzo if (status & I2C_STAT_NACK) { 660239281Sgonzo /* no ACK from slave */ 661239281Sgonzo ti_i2c_dbg(sc, "NACK\n"); 662239281Sgonzo err = ENXIO; 663239281Sgonzo break; 664239281Sgonzo } 665239281Sgonzo if (status & I2C_STAT_AL) { 666239281Sgonzo /* arbitration lost */ 667239281Sgonzo ti_i2c_dbg(sc, "Arbitration lost\n"); 668239281Sgonzo err = ENXIO; 669239281Sgonzo break; 670239281Sgonzo } 671239281Sgonzo 672239281Sgonzo /* check if we have finished */ 673239281Sgonzo if (status & I2C_STAT_ARDY) { 674239281Sgonzo /* register access ready - transaction complete basically */ 675239281Sgonzo ti_i2c_dbg(sc, "ARDY transaction complete\n"); 676239281Sgonzo err = 0; 677239281Sgonzo break; 678239281Sgonzo } 679239281Sgonzo 680239281Sgonzo /* read some data */ 681239281Sgonzo if (status & I2C_STAT_XDR) { 682239281Sgonzo /* Receive draining interrupt - last data received */ 683239281Sgonzo ti_i2c_dbg(sc, "Transmit draining interrupt\n"); 684239281Sgonzo 685239281Sgonzo /* get the number of bytes in the FIFO */ 686239281Sgonzo amount = ti_i2c_read_reg(sc, I2C_REG_BUFSTAT); 687239281Sgonzo amount &= 0x3f; 688239281Sgonzo } 689239281Sgonzo else if (status & I2C_STAT_XRDY) { 690239281Sgonzo /* Receive data ready interrupt - enough data received */ 691239281Sgonzo ti_i2c_dbg(sc, "Transmit data ready interrupt\n"); 692239281Sgonzo 693239281Sgonzo /* get the number of bytes in the FIFO */ 694239281Sgonzo amount = ti_i2c_read_reg(sc, I2C_REG_BUF); 695239281Sgonzo amount &= 0x3f; 696239281Sgonzo amount += 1; 697239281Sgonzo } 698239281Sgonzo 699239281Sgonzo /* sanity check we haven't overwritten the array */ 700239281Sgonzo if ((sofar + amount) > len) { 701239281Sgonzo ti_i2c_dbg(sc, "to many bytes to write\n"); 702239281Sgonzo amount = (len - sofar); 703239281Sgonzo } 704239281Sgonzo 705239281Sgonzo /* write the bytes from the fifo */ 706239281Sgonzo for (i = 0; i < amount; i++) { 707239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_DATA, buf[sofar++]); 708239281Sgonzo } 709239281Sgonzo 710239281Sgonzo /* attempt to clear the transmit ready bits */ 711239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_STAT, I2C_STAT_XDR | I2C_STAT_XRDY); 712239281Sgonzo } 713239281Sgonzo 714239281Sgonzo /* reset the registers regardless if there was an error or not */ 715239281Sgonzo ti_i2c_set_intr_enable(sc, 0x0000); 716239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, I2C_CON_I2C_EN | I2C_CON_MST | I2C_CON_STP); 717239281Sgonzo 718239281Sgonzo return (err); 719239281Sgonzo} 720239281Sgonzo 721239281Sgonzo/** 722239281Sgonzo * ti_i2c_transfer - called to perform the transfer 723239281Sgonzo * @dev: i2c device handle 724239281Sgonzo * @msgs: the messages to send/receive 725239281Sgonzo * @nmsgs: the number of messages in the msgs array 726239281Sgonzo * 727239281Sgonzo * 728239281Sgonzo * LOCKING: 729239281Sgonzo * Internally locked 730239281Sgonzo * 731239281Sgonzo * RETURNS: 732239281Sgonzo * 0 on function succeeded 733239281Sgonzo * EINVAL if invalid message is passed as an arg 734239281Sgonzo */ 735239281Sgonzostatic int 736239281Sgonzoti_i2c_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) 737239281Sgonzo{ 738239281Sgonzo struct ti_i2c_softc *sc = device_get_softc(dev); 739239281Sgonzo int err = 0; 740239281Sgonzo uint32_t i; 741239281Sgonzo uint16_t len; 742239281Sgonzo uint8_t *buf; 743239281Sgonzo 744239281Sgonzo TI_I2C_LOCK(sc); 745239281Sgonzo 746239281Sgonzo for (i = 0; i < nmsgs; i++) { 747239281Sgonzo 748239281Sgonzo len = msgs[i].len; 749239281Sgonzo buf = msgs[i].buf; 750239281Sgonzo 751239281Sgonzo /* zero byte transfers aren't allowed */ 752239281Sgonzo if (len == 0 || buf == NULL) { 753239281Sgonzo err = EINVAL; 754239281Sgonzo goto out; 755239281Sgonzo } 756239281Sgonzo 757239281Sgonzo /* set the slave address */ 758239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_SA, msgs[i].slave); 759239281Sgonzo 760239281Sgonzo /* perform the read or write */ 761239281Sgonzo if (msgs[i].flags & IIC_M_RD) { 762239281Sgonzo err = ti_i2c_read_bytes(sc, buf, len); 763239281Sgonzo } else { 764239281Sgonzo err = ti_i2c_write_bytes(sc, buf, len); 765239281Sgonzo } 766239281Sgonzo 767239281Sgonzo } 768239281Sgonzo 769239281Sgonzoout: 770239281Sgonzo TI_I2C_UNLOCK(sc); 771239281Sgonzo 772239281Sgonzo return (err); 773239281Sgonzo} 774239281Sgonzo 775239281Sgonzo/** 776239281Sgonzo * ti_i2c_callback - not sure about this one 777239281Sgonzo * @dev: i2c device handle 778239281Sgonzo * 779239281Sgonzo * 780239281Sgonzo * 781239281Sgonzo * LOCKING: 782239281Sgonzo * Called from timer context 783239281Sgonzo * 784239281Sgonzo * RETURNS: 785239281Sgonzo * EH_HANDLED or EH_NOT_HANDLED 786239281Sgonzo */ 787239281Sgonzostatic int 788239281Sgonzoti_i2c_callback(device_t dev, int index, caddr_t data) 789239281Sgonzo{ 790239281Sgonzo int error = 0; 791239281Sgonzo 792239281Sgonzo switch (index) { 793239281Sgonzo case IIC_REQUEST_BUS: 794239281Sgonzo break; 795239281Sgonzo 796239281Sgonzo case IIC_RELEASE_BUS: 797239281Sgonzo break; 798239281Sgonzo 799239281Sgonzo default: 800239281Sgonzo error = EINVAL; 801239281Sgonzo } 802239281Sgonzo 803239281Sgonzo return (error); 804239281Sgonzo} 805239281Sgonzo 806239281Sgonzo/** 807239281Sgonzo * ti_i2c_activate - initialises and activates an I2C bus 808239281Sgonzo * @dev: i2c device handle 809239281Sgonzo * @num: the number of the I2C controller to activate; 1, 2 or 3 810239281Sgonzo * 811239281Sgonzo * 812239281Sgonzo * LOCKING: 813239281Sgonzo * Assumed called in an atomic context. 814239281Sgonzo * 815239281Sgonzo * RETURNS: 816239281Sgonzo * nothing 817239281Sgonzo */ 818239281Sgonzostatic int 819239281Sgonzoti_i2c_activate(device_t dev) 820239281Sgonzo{ 821239281Sgonzo struct ti_i2c_softc *sc = (struct ti_i2c_softc*) device_get_softc(dev); 822239281Sgonzo unsigned int timeout = 0; 823239281Sgonzo uint16_t con_reg; 824239281Sgonzo int err; 825239281Sgonzo clk_ident_t clk; 826239281Sgonzo 827239281Sgonzo /* 828239281Sgonzo * The following sequence is taken from the OMAP3530 technical reference 829239281Sgonzo * 830239281Sgonzo * 1. Enable the functional and interface clocks (see Section 18.3.1.1.1). 831239281Sgonzo */ 832239281Sgonzo clk = I2C0_CLK + sc->device_id; 833239281Sgonzo err = ti_prcm_clk_enable(clk); 834239281Sgonzo if (err) 835239281Sgonzo return (err); 836239281Sgonzo 837239281Sgonzo /* There seems to be a bug in the I2C reset mechanism, for some reason you 838239281Sgonzo * need to disable the I2C module before issuing the reset and then enable 839239281Sgonzo * it again after to detect the reset done. 840239281Sgonzo * 841239281Sgonzo * I found this out by looking at the Linux driver implementation, thanks 842239281Sgonzo * linux guys! 843239281Sgonzo */ 844239281Sgonzo 845239281Sgonzo /* Disable the I2C controller */ 846239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, 0x0000); 847239281Sgonzo 848239281Sgonzo /* Issue a softreset to the controller */ 849239281Sgonzo /* XXXOMAP3: FIXME */ 850239281Sgonzo bus_write_2(sc->sc_mem_res, I2C_REG_SYSC, 0x0002); 851239281Sgonzo 852239281Sgonzo /* Re-enable the module and then check for the reset done */ 853239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, I2C_CON_I2C_EN); 854239281Sgonzo 855239281Sgonzo while ((ti_i2c_read_reg(sc, I2C_REG_SYSS) & 0x01) == 0x00) { 856239281Sgonzo if (timeout++ > 100) { 857239281Sgonzo return (EBUSY); 858239281Sgonzo } 859239281Sgonzo DELAY(100); 860239281Sgonzo } 861239281Sgonzo 862239281Sgonzo /* Disable the I2C controller once again, now that the reset has finished */ 863239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, 0x0000); 864239281Sgonzo 865239281Sgonzo /* 2. Program the prescaler to obtain an approximately 12-MHz internal 866239281Sgonzo * sampling clock (I2Ci_INTERNAL_CLK) by programming the corresponding 867239281Sgonzo * value in the I2Ci.I2C_PSC[3:0] PSC field. 868239281Sgonzo * This value depends on the frequency of the functional clock (I2Ci_FCLK). 869239281Sgonzo * Because this frequency is 96MHz, the I2Ci.I2C_PSC[7:0] PSC field value 870239281Sgonzo * is 0x7. 871239281Sgonzo */ 872239281Sgonzo 873239281Sgonzo /* Program the prescaler to obtain an approximately 12-MHz internal 874239281Sgonzo * sampling clock. 875239281Sgonzo */ 876239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_PSC, 0x0017); 877239281Sgonzo 878239281Sgonzo /* 3. Program the I2Ci.I2C_SCLL[7:0] SCLL and I2Ci.I2C_SCLH[7:0] SCLH fields 879239281Sgonzo * to obtain a bit rate of 100K bps or 400K bps. These values depend on 880239281Sgonzo * the internal sampling clock frequency (see Table 18-12). 881239281Sgonzo */ 882239281Sgonzo 883239281Sgonzo /* Set the bitrate to 100kbps */ 884239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_SCLL, 0x000d); 885239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_SCLH, 0x000f); 886239281Sgonzo 887239281Sgonzo /* 4. (Optional) Program the I2Ci.I2C_SCLL[15:8] HSSCLL and 888239281Sgonzo * I2Ci.I2C_SCLH[15:8] HSSCLH fields to obtain a bit rate of 400K bps or 889239281Sgonzo * 3.4M bps (for the second phase of HS mode). These values depend on the 890239281Sgonzo * internal sampling clock frequency (see Table 18-12). 891239281Sgonzo * 892239281Sgonzo * 5. (Optional) If a bit rate of 3.4M bps is used and the bus line 893239281Sgonzo * capacitance exceeds 45 pF, program the CONTROL.CONTROL_DEVCONF1[12] 894239281Sgonzo * I2C1HSMASTER bit for I2C1, the CONTROL.CONTROL_DEVCONF1[13] 895239281Sgonzo * I2C2HSMASTER bit for I2C2, or the CONTROL.CONTROL_DEVCONF1[14] 896239281Sgonzo * I2C3HSMASTER bit for I2C3. 897239281Sgonzo */ 898239281Sgonzo 899239281Sgonzo /* 6. Configure the Own Address of the I2C controller by storing it in the 900239281Sgonzo * I2Ci.I2C_OA0 register. Up to four Own Addresses can be programmed in 901239281Sgonzo * the I2Ci.I2C_OAi registers (with I = 0, 1, 2, 3) for each I2C 902239281Sgonzo * controller. 903239281Sgonzo * 904239281Sgonzo * Note: For a 10-bit address, set the corresponding expand Own Address bit 905239281Sgonzo * in the I2Ci.I2C_CON register. 906239281Sgonzo */ 907239281Sgonzo 908239281Sgonzo /* Driver currently always in single master mode so ignore this step */ 909239281Sgonzo 910239281Sgonzo /* 7. Set the TX threshold (in transmitter mode) and the RX threshold (in 911239281Sgonzo * receiver mode) by setting the I2Ci.I2C_BUF[5:0]XTRSH field to (TX 912239281Sgonzo * threshold - 1) and the I2Ci.I2C_BUF[13:8]RTRSH field to (RX threshold 913239281Sgonzo * - 1), where the TX and RX thresholds are greater than or equal to 1. 914239281Sgonzo */ 915239281Sgonzo 916239281Sgonzo /* Set the FIFO buffer threshold, note I2C1 & I2C2 have 8 byte FIFO, whereas 917239281Sgonzo * I2C3 has 64 bytes. Threshold set to 5 for now. 918239281Sgonzo */ 919239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_BUF, 0x0404); 920239281Sgonzo 921239281Sgonzo /* 922239281Sgonzo * 8. Take the I2C controller out of reset by setting the I2Ci.I2C_CON[15] 923239281Sgonzo * I2C_EN bit to 1. 924239281Sgonzo */ 925239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, I2C_CON_I2C_EN | I2C_CON_OPMODE_STD); 926239281Sgonzo 927239281Sgonzo /* 928239281Sgonzo * To initialize the I2C controller, perform the following steps: 929239281Sgonzo * 930239281Sgonzo * 1. Configure the I2Ci.I2C_CON register: 931239281Sgonzo * �� For master or slave mode, set the I2Ci.I2C_CON[10] MST bit (0: slave, 932239281Sgonzo * 1: master). 933239281Sgonzo * �� For transmitter or receiver mode, set the I2Ci.I2C_CON[9] TRX bit 934239281Sgonzo * (0: receiver, 1: transmitter). 935239281Sgonzo */ 936239281Sgonzo con_reg = ti_i2c_read_reg(sc, I2C_REG_CON); 937239281Sgonzo con_reg |= I2C_CON_MST; 938239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, con_reg); 939239281Sgonzo 940239281Sgonzo /* 2. If using an interrupt to transmit/receive data, set to 1 the 941239281Sgonzo * corresponding bit in the I2Ci.I2C_IE register (the I2Ci.I2C_IE[4] 942239281Sgonzo * XRDY_IE bit for the transmit interrupt, the I2Ci.I2C_IE[3] RRDY bit 943239281Sgonzo * for the receive interrupt). 944239281Sgonzo */ 945239281Sgonzo ti_i2c_set_intr_enable(sc, I2C_IE_XRDY | I2C_IE_RRDY); 946239281Sgonzo 947239281Sgonzo /* 3. If using DMA to receive/transmit data, set to 1 the corresponding bit 948239281Sgonzo * in the I2Ci.I2C_BUF register (the I2Ci.I2C_BUF[15] RDMA_EN bit for the 949239281Sgonzo * receive DMA channel, the I2Ci.I2C_BUF[7] XDMA_EN bit for the transmit 950239281Sgonzo * DMA channel). 951239281Sgonzo */ 952239281Sgonzo 953239281Sgonzo /* not using DMA for now, so ignore this */ 954239281Sgonzo 955239281Sgonzo return (0); 956239281Sgonzo} 957239281Sgonzo 958239281Sgonzo/** 959239281Sgonzo * ti_i2c_deactivate - deactivates the controller and releases resources 960239281Sgonzo * @dev: i2c device handle 961239281Sgonzo * 962239281Sgonzo * 963239281Sgonzo * 964239281Sgonzo * LOCKING: 965239281Sgonzo * Assumed called in an atomic context. 966239281Sgonzo * 967239281Sgonzo * RETURNS: 968239281Sgonzo * nothing 969239281Sgonzo */ 970239281Sgonzostatic void 971239281Sgonzoti_i2c_deactivate(device_t dev) 972239281Sgonzo{ 973239281Sgonzo struct ti_i2c_softc *sc = device_get_softc(dev); 974239281Sgonzo clk_ident_t clk; 975239281Sgonzo 976239281Sgonzo /* Disable the controller - cancel all transactions */ 977239281Sgonzo ti_i2c_write_reg(sc, I2C_REG_CON, 0x0000); 978239281Sgonzo 979239281Sgonzo /* Release the interrupt handler */ 980239281Sgonzo if (sc->sc_irq_h) { 981239281Sgonzo bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_h); 982239281Sgonzo sc->sc_irq_h = 0; 983239281Sgonzo } 984239281Sgonzo 985239281Sgonzo bus_generic_detach(sc->sc_dev); 986239281Sgonzo 987239281Sgonzo /* Unmap the I2C controller registers */ 988239281Sgonzo if (sc->sc_mem_res != 0) { 989239281Sgonzo bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_irq_res), 990239281Sgonzo sc->sc_mem_res); 991239281Sgonzo sc->sc_mem_res = NULL; 992239281Sgonzo } 993239281Sgonzo 994239281Sgonzo /* Release the IRQ resource */ 995239281Sgonzo if (sc->sc_irq_res != NULL) { 996239281Sgonzo bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->sc_irq_res), 997239281Sgonzo sc->sc_irq_res); 998239281Sgonzo sc->sc_irq_res = NULL; 999239281Sgonzo } 1000239281Sgonzo 1001239281Sgonzo /* Finally disable the functional and interface clocks */ 1002239281Sgonzo clk = I2C0_CLK + sc->device_id; 1003239281Sgonzo ti_prcm_clk_disable(clk); 1004239281Sgonzo 1005239281Sgonzo return; 1006239281Sgonzo} 1007239281Sgonzo 1008239281Sgonzo/** 1009239281Sgonzo * ti_i2c_probe - probe function for the driver 1010239281Sgonzo * @dev: i2c device handle 1011239281Sgonzo * 1012239281Sgonzo * 1013239281Sgonzo * 1014239281Sgonzo * LOCKING: 1015239281Sgonzo * 1016239281Sgonzo * 1017239281Sgonzo * RETURNS: 1018239281Sgonzo * Always returns 0 1019239281Sgonzo */ 1020239281Sgonzostatic int 1021239281Sgonzoti_i2c_probe(device_t dev) 1022239281Sgonzo{ 1023239281Sgonzo if (!ofw_bus_is_compatible(dev, "ti,i2c")) 1024239281Sgonzo return (ENXIO); 1025239281Sgonzo 1026239281Sgonzo device_set_desc(dev, "TI I2C Controller"); 1027239281Sgonzo return (0); 1028239281Sgonzo} 1029239281Sgonzo 1030239281Sgonzo/** 1031239281Sgonzo * ti_i2c_attach - attach function for the driver 1032239281Sgonzo * @dev: i2c device handle 1033239281Sgonzo * 1034239281Sgonzo * Initialised driver data structures and activates the I2C controller. 1035239281Sgonzo * 1036239281Sgonzo * LOCKING: 1037239281Sgonzo * 1038239281Sgonzo * 1039239281Sgonzo * RETURNS: 1040239281Sgonzo * 1041239281Sgonzo */ 1042239281Sgonzostatic int 1043239281Sgonzoti_i2c_attach(device_t dev) 1044239281Sgonzo{ 1045239281Sgonzo struct ti_i2c_softc *sc = device_get_softc(dev); 1046239281Sgonzo phandle_t node; 1047239281Sgonzo pcell_t did; 1048239281Sgonzo int err; 1049239281Sgonzo int rid; 1050239281Sgonzo 1051239281Sgonzo sc->sc_dev = dev; 1052239281Sgonzo 1053239281Sgonzo /* Get the i2c device id from FDT */ 1054239281Sgonzo node = ofw_bus_get_node(dev); 1055239281Sgonzo if ((OF_getprop(node, "i2c-device-id", &did, sizeof(did))) <= 0) { 1056239281Sgonzo device_printf(dev, "missing i2c-device-id attribute in FDT\n"); 1057239281Sgonzo return (ENXIO); 1058239281Sgonzo } 1059239281Sgonzo sc->device_id = fdt32_to_cpu(did); 1060239281Sgonzo 1061239281Sgonzo TI_I2C_LOCK_INIT(sc); 1062239281Sgonzo 1063239281Sgonzo /* Get the memory resource for the register mapping */ 1064239281Sgonzo rid = 0; 1065239281Sgonzo sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 1066239281Sgonzo RF_ACTIVE); 1067239281Sgonzo if (sc->sc_mem_res == NULL) 1068239281Sgonzo panic("%s: Cannot map registers", device_get_name(dev)); 1069239281Sgonzo 1070239281Sgonzo /* Allocate an IRQ resource for the MMC controller */ 1071239281Sgonzo rid = 0; 1072239281Sgonzo sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 1073239281Sgonzo RF_ACTIVE | RF_SHAREABLE); 1074239281Sgonzo if (sc->sc_irq_res == NULL) { 1075239281Sgonzo err = ENOMEM; 1076239281Sgonzo goto out; 1077239281Sgonzo } 1078239281Sgonzo 1079239281Sgonzo /* XXXOMAP3: FIXME get proper revision here */ 1080239281Sgonzo /* First read the version number of the I2C module */ 1081239281Sgonzo sc->sc_rev = ti_i2c_read_2(sc, I2C_REG_REVNB_HI) & 0xff; 1082239281Sgonzo 1083239281Sgonzo device_printf(dev, "I2C revision %d.%d\n", sc->sc_rev >> 4, 1084239281Sgonzo sc->sc_rev & 0xf); 1085239281Sgonzo 1086239281Sgonzo /* Activate the H/W */ 1087239281Sgonzo err = ti_i2c_activate(dev); 1088239281Sgonzo if (err) { 1089239281Sgonzo device_printf(dev, "ti_i2c_activate failed\n"); 1090239281Sgonzo goto out; 1091239281Sgonzo } 1092239281Sgonzo 1093239281Sgonzo /* activate the interrupt */ 1094239281Sgonzo err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 1095239281Sgonzo NULL, ti_i2c_intr, sc, &sc->sc_irq_h); 1096239281Sgonzo if (err) 1097239281Sgonzo goto out; 1098239281Sgonzo 1099239281Sgonzo /* Attach to the iicbus */ 1100239281Sgonzo if ((sc->sc_iicbus = device_add_child(dev, "iicbus", -1)) == NULL) 1101239281Sgonzo device_printf(dev, "could not allocate iicbus instance\n"); 1102239281Sgonzo 1103239281Sgonzo /* Probe and attach the iicbus */ 1104239281Sgonzo bus_generic_attach(dev); 1105239281Sgonzo 1106239281Sgonzoout: 1107239281Sgonzo if (err) { 1108239281Sgonzo ti_i2c_deactivate(dev); 1109239281Sgonzo TI_I2C_LOCK_DESTROY(sc); 1110239281Sgonzo } 1111239281Sgonzo 1112239281Sgonzo return (err); 1113239281Sgonzo} 1114239281Sgonzo 1115239281Sgonzo/** 1116239281Sgonzo * ti_i2c_detach - detach function for the driver 1117239281Sgonzo * @dev: i2c device handle 1118239281Sgonzo * 1119239281Sgonzo * 1120239281Sgonzo * 1121239281Sgonzo * LOCKING: 1122239281Sgonzo * 1123239281Sgonzo * 1124239281Sgonzo * RETURNS: 1125239281Sgonzo * Always returns 0 1126239281Sgonzo */ 1127239281Sgonzostatic int 1128239281Sgonzoti_i2c_detach(device_t dev) 1129239281Sgonzo{ 1130239281Sgonzo struct ti_i2c_softc *sc = device_get_softc(dev); 1131239281Sgonzo int rv; 1132239281Sgonzo 1133239281Sgonzo ti_i2c_deactivate(dev); 1134239281Sgonzo 1135239281Sgonzo if (sc->sc_iicbus && (rv = device_delete_child(dev, sc->sc_iicbus)) != 0) 1136239281Sgonzo return (rv); 1137239281Sgonzo 1138239281Sgonzo TI_I2C_LOCK_DESTROY(sc); 1139239281Sgonzo 1140239281Sgonzo return (0); 1141239281Sgonzo} 1142239281Sgonzo 1143239281Sgonzo 1144239281Sgonzostatic phandle_t 1145239281Sgonzoti_i2c_get_node(device_t bus, device_t dev) 1146239281Sgonzo{ 1147239281Sgonzo /* 1148239281Sgonzo * Share controller node with iibus device 1149239281Sgonzo */ 1150239281Sgonzo return ofw_bus_get_node(bus); 1151239281Sgonzo} 1152239281Sgonzo 1153239281Sgonzostatic device_method_t ti_i2c_methods[] = { 1154239281Sgonzo /* Device interface */ 1155239281Sgonzo DEVMETHOD(device_probe, ti_i2c_probe), 1156239281Sgonzo DEVMETHOD(device_attach, ti_i2c_attach), 1157239281Sgonzo DEVMETHOD(device_detach, ti_i2c_detach), 1158239281Sgonzo 1159239281Sgonzo /* OFW methods */ 1160239281Sgonzo DEVMETHOD(ofw_bus_get_node, ti_i2c_get_node), 1161239281Sgonzo 1162239281Sgonzo /* iicbus interface */ 1163239281Sgonzo DEVMETHOD(iicbus_callback, ti_i2c_callback), 1164239281Sgonzo DEVMETHOD(iicbus_reset, ti_i2c_reset), 1165239281Sgonzo DEVMETHOD(iicbus_transfer, ti_i2c_transfer), 1166239281Sgonzo { 0, 0 } 1167239281Sgonzo}; 1168239281Sgonzo 1169239281Sgonzostatic driver_t ti_i2c_driver = { 1170239281Sgonzo "iichb", 1171239281Sgonzo ti_i2c_methods, 1172239281Sgonzo sizeof(struct ti_i2c_softc), 1173239281Sgonzo}; 1174239281Sgonzo 1175239281SgonzoDRIVER_MODULE(ti_iic, simplebus, ti_i2c_driver, ti_i2c_devclass, 0, 0); 1176239281SgonzoDRIVER_MODULE(iicbus, ti_iic, iicbus_driver, iicbus_devclass, 0, 0); 1177239281Sgonzo 1178239281SgonzoMODULE_DEPEND(ti_iic, ti_prcm, 1, 1, 1); 1179239281SgonzoMODULE_DEPEND(ti_iic, iicbus, 1, 1, 1); 1180