/* set SDA and SCL as GPIO */ #define DAVINCI_I2C_FUNC_PFUNC0 BIT(0)
/* set SCL as output when used as GPIO*/ #define DAVINCI_I2C_DIR_PDIR0 BIT(0) /* set SDA as output when used as GPIO*/ #define DAVINCI_I2C_DIR_PDIR1 BIT(1)
staticinlinevoid davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, int val)
{
u16 w;
w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG); if (!val) /* put I2C into reset */
w &= ~DAVINCI_I2C_MDR_IRS; else/* take I2C out of reset */
w |= DAVINCI_I2C_MDR_IRS;
/* NOTE: I2C Clock divider programming info * As per I2C specs the following formulas provide prescaler * and low/high divider values * input clk --> PSC Div -----------> ICCL/H Div --> output clock * module clk * * output clk = module clk / (PSC + 1) [ (ICCL + d) + (ICCH + d) ] * * Thus, * (ICCL + ICCH) = clk = (input clk / ((psc +1) * output clk)) - 2d; * * where if PSC == 0, d = 7, * if PSC == 1, d = 6 * if PSC > 1 , d = 5 * * Note: * d is always 6 on Keystone I2C controller
*/
/* * Both Davinci and current Keystone User Guides recommend a value * between 7MHz and 12MHz. In reality 7MHz module clock doesn't * always produce enough margin between SDA and SCL transitions. * Measurements show that the higher the module clock is, the * bigger is the margin, providing more reliable communication. * So we better target for 12MHz.
*/
psc = (input_clock / 12000000) - 1; if ((input_clock / (psc + 1)) > 12000000)
psc++; /* better to run under spec than over */
d = (psc >= 2) ? 5 : 7 - psc;
if (device_is_compatible(dev->dev, "ti,keystone-i2c"))
d = 6;
clk = ((input_clock / (psc + 1)) / (dev->bus_freq * 1000)); /* Avoid driving the bus too fast because of rounding errors above */ if (input_clock / (psc + 1) / clk > dev->bus_freq * 1000)
clk++; /* * According to I2C-BUS Spec 2.1, in FAST-MODE LOW period should be at * least 1.3uS, which is not the case with 50% duty cycle. Driving HIGH * to LOW ratio as 1 to 2 is more safe.
*/ if (dev->bus_freq > 100)
clkl = (clk << 1) / 3; else
clkl = (clk >> 1); /* * It's not always possible to have 1 to 2 ratio when d=7, so fall back * to minimal possible clkh in this case. * * Note: * CLKH is not allowed to be 0, in this case I2C clock is not generated * at all
*/ if (clk > clkl + d) {
clkh = clk - clkl - d;
clkl -= d;
} else {
clkh = 1;
clkl = clk - (d << 1);
}
/* * This function configures I2C and brings I2C out of reset. * This function is called during I2C init function. This function * also gets called if I2C encounters any errors.
*/ staticint i2c_davinci_init(struct davinci_i2c_dev *dev)
{ /* put I2C into reset */
davinci_i2c_reset_ctrl(dev, 0);
/* Respond at reserved "SMBus Host" target address" (and zero); * we seem to have no option to not respond...
*/
davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, DAVINCI_I2C_OWN_ADDRESS);
/* * This routine does i2c bus recovery by using i2c_generic_scl_recovery * which is provided by I2C Bus recovery infrastructure.
*/ staticvoid davinci_i2c_prepare_recovery(struct i2c_adapter *adap)
{ struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
/* * Waiting for bus not busy
*/ staticint i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev)
{ unsignedlong timeout = jiffies + dev->adapter.timeout;
do { if (!(davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) & DAVINCI_I2C_STR_BB)) return 0;
schedule_timeout_uninterruptible(1);
} while (time_before_eq(jiffies, timeout));
dev_warn(dev->dev, "timeout waiting for bus ready\n");
i2c_recover_bus(&dev->adapter);
/* * if bus is still "busy" here, it's most probably a HW problem like * short-circuit
*/ if (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) & DAVINCI_I2C_STR_BB) return -EIO;
return 0;
}
/* * Low level read/write transaction. This function is called from * i2c_davinci_xfer.
*/ staticint
i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
{ struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
u32 flag;
u16 w; unsignedlong time_left;
if (msg->addr == DAVINCI_I2C_OWN_ADDRESS) {
dev_warn(dev->dev, "transfer to own address aborted\n"); return -EADDRNOTAVAIL;
}
/* set the target address */
davinci_i2c_write_reg(dev, DAVINCI_I2C_SAR_REG, msg->addr);
/* Take I2C out of reset and configure it as controller */
flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST;
if (msg->flags & I2C_M_TEN)
flag |= DAVINCI_I2C_MDR_XA; if (!(msg->flags & I2C_M_RD))
flag |= DAVINCI_I2C_MDR_TRX; if (msg->len == 0)
flag |= DAVINCI_I2C_MDR_RM;
/* Enable receive or transmit interrupts */
w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); if (msg->flags & I2C_M_RD)
w |= DAVINCI_I2C_IMR_RRDY; else
w |= DAVINCI_I2C_IMR_XRDY;
davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w);
dev->terminate = 0;
/* * Write mode register first as needed for correct behaviour * on OMAP-L138, but don't set STT yet to avoid a race with XRDY * occurring before we have loaded DXR
*/
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
/* * First byte should be set here, not after interrupt, * because transmit-data-ready interrupt can come before * NACK-interrupt during sending of previous message and * ICDXR may have wrong data * It also saves us one interrupt, slightly faster
*/ if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) {
davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++);
dev->buf_len--;
}
/* Set STT to begin transmit now DXR is loaded */
flag |= DAVINCI_I2C_MDR_STT; if (stop && msg->len != 0)
flag |= DAVINCI_I2C_MDR_STP;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
time_left = wait_for_completion_timeout(&dev->cmd_complete,
dev->adapter.timeout); if (!time_left) {
i2c_recover_bus(adap);
dev->buf_len = 0; return -ETIMEDOUT;
} if (dev->buf_len) { /* This should be 0 if all bytes were transferred * or dev->cmd_err denotes an error.
*/
dev_err(dev->dev, "abnormal termination buf_len=%zu\n",
dev->buf_len);
dev->terminate = 1;
wmb();
dev->buf_len = 0; return -EREMOTEIO;
}
/* no error */ if (likely(!dev->cmd_err)) return msg->len;
/* We have an error */ if (dev->cmd_err & DAVINCI_I2C_STR_AL) {
i2c_davinci_init(dev); return -EIO;
}
if (dev->cmd_err & DAVINCI_I2C_STR_NACK) { if (msg->flags & I2C_M_IGNORE_NAK) return msg->len;
w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
w |= DAVINCI_I2C_MDR_STP;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); return -EREMOTEIO;
} return -EIO;
}
/* * Prepare controller for a transaction and call i2c_davinci_xfer_msg
*/ staticint
i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{ struct davinci_i2c_dev *dev = i2c_get_adapdata(adap); int i; int ret;
staticvoid terminate_read(struct davinci_i2c_dev *dev)
{
u16 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
w |= DAVINCI_I2C_MDR_NACK;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
/* Throw away data */
davinci_i2c_read_reg(dev, DAVINCI_I2C_DRR_REG); if (!dev->terminate)
dev_err(dev->dev, "RDR IRQ while no data requested\n");
} staticvoid terminate_write(struct davinci_i2c_dev *dev)
{
u16 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
w |= DAVINCI_I2C_MDR_RM | DAVINCI_I2C_MDR_STP;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
if (!dev->terminate)
dev_dbg(dev->dev, "TDR IRQ while no data to send\n");
}
/* * Interrupt service routine. This gets called whenever an I2C interrupt * occurs.
*/ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
{ struct davinci_i2c_dev *dev = dev_id;
u32 stat; int count = 0;
u16 w;
if (pm_runtime_suspended(dev->dev)) return IRQ_NONE;
while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat); if (count++ == 100) {
dev_warn(dev->dev, "Too much work in one IRQ\n"); break;
}
switch (stat) { case DAVINCI_I2C_IVR_AL: /* Arbitration lost, must retry */
dev->cmd_err |= DAVINCI_I2C_STR_AL;
dev->buf_len = 0;
complete(&dev->cmd_complete); break;
case DAVINCI_I2C_IVR_NACK:
dev->cmd_err |= DAVINCI_I2C_STR_NACK;
dev->buf_len = 0;
complete(&dev->cmd_complete); break;
case DAVINCI_I2C_IVR_ARDY:
davinci_i2c_write_reg(dev,
DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY); if (((dev->buf_len == 0) && (dev->stop != 0)) ||
(dev->cmd_err & DAVINCI_I2C_STR_NACK)) {
w = davinci_i2c_read_reg(dev,
DAVINCI_I2C_MDR_REG);
w |= DAVINCI_I2C_MDR_STP;
davinci_i2c_write_reg(dev,
DAVINCI_I2C_MDR_REG, w);
}
complete(&dev->cmd_complete); break;
case DAVINCI_I2C_IVR_RDR: if (dev->buf_len) {
*dev->buf++ =
davinci_i2c_read_reg(dev,
DAVINCI_I2C_DRR_REG);
dev->buf_len--; if (dev->buf_len) continue;
davinci_i2c_write_reg(dev,
DAVINCI_I2C_STR_REG,
DAVINCI_I2C_IMR_RRDY);
} else { /* signal can terminate transfer */
terminate_read(dev);
} break;
case DAVINCI_I2C_IVR_XRDY: if (dev->buf_len) {
davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG,
*dev->buf++);
dev->buf_len--; if (dev->buf_len) continue;
w = davinci_i2c_read_reg(dev,
DAVINCI_I2C_IMR_REG);
w &= ~DAVINCI_I2C_IMR_XRDY;
davinci_i2c_write_reg(dev,
DAVINCI_I2C_IMR_REG,
w);
} else { /* signal can terminate transfer */
terminate_write(dev);
} break;
case DAVINCI_I2C_IVR_SCD:
davinci_i2c_write_reg(dev,
DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_SCD);
complete(&dev->cmd_complete); break;
case DAVINCI_I2C_IVR_AAS:
dev_dbg(dev->dev, "Address as target interrupt\n"); break;
default:
dev_warn(dev->dev, "Unrecognized irq stat %d\n", stat); break;
}
}
/* I2C may be needed to bring up other drivers */ staticint __init davinci_i2c_init_driver(void)
{ return platform_driver_register(&davinci_i2c_driver);
}
subsys_initcall(davinci_i2c_init_driver);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.