static irqreturn_t rk30_i2c_irq(int irq, void *dev_id)
{
        struct rk30_i2c *i2c = dev_id;
        unsigned int ipd;

        spin_lock(&i2c->lock);
        ipd = i2c_readl(i2c->regs + I2C_IPD);
        if(i2c->state == STATE_IDLE){
                dev_info(i2c->dev, "Addr[0x%02x]  irq in STATE_IDLE, ipd = 0x%x\n", i2c->addr, ipd);
                i2c_writel(I2C_IPD_ALL_CLEAN, i2c->regs + I2C_IPD);
                goto out;
        }

#if defined(CONFIG_MFD_TRS65910)	//for trs65910 Trsilicon peter
	if(ipd & I2C_NAKRCVIPD && i2c->addr == 0x2d){
		i2c_writel(I2C_NAKRCVIPD, i2c->regs + I2C_IPD);
		goto out;
	}else  if(ipd & I2C_NAKRCVIPD){
		i2c_writel(I2C_NAKRCVIPD, i2c->regs + I2C_IPD);
		i2c->error = -EAGAIN;
		goto out;
	}
#else
	if(ipd & I2C_NAKRCVIPD){
		i2c_writel(I2C_NAKRCVIPD, i2c->regs + I2C_IPD);
		i2c->error = -EAGAIN;
		goto out;
	}
#endif
        rk30_i2c_irq_nextblock(i2c, ipd);
out:
        spin_unlock(&i2c->lock);
        return IRQ_HANDLED;
}
static void rk30_irq_write_prepare(struct rk30_i2c *i2c)
{
    unsigned int data = 0, cnt = 0, i, j;
    unsigned char byte;

    if(is_msgend(i2c)) {
        rk30_i2c_stop(i2c, i2c->error);
        return;
    }
    for(i = 0; i < 8; i++) {
        data = 0;
        for(j = 0; j < 4; j++) {
            if(is_msgend(i2c))
                break;
            if(i2c->msg_ptr == 0 && cnt == 0)
                byte = (i2c->addr & 0x7f) << 1;
            else
                byte =  i2c->msg->buf[i2c->msg_ptr++];
            cnt++;
            data |= (byte << (j * 8));
        }
        i2c_writel(data, i2c->regs + I2C_TXDATA_BASE + 4 * i);
        if(is_msgend(i2c))
            break;
    }
    i2c_writel(cnt, i2c->regs + I2C_MTXCNT);
}
예제 #3
0
static void i2c_lpc2k_reset(struct lpc2k_i2c *i2c)
{
	/* Will force clear all statuses */
	i2c_writel(0x7C, i2c->reg_base + LPC24XX_I2CONCLR);
	i2c_writel(0, i2c->reg_base + LPC24XX_I2ADDR);
	i2c_writel(LPC24XX_I2EN, i2c->reg_base + LPC24XX_I2CONSET);
}
예제 #4
0
파일: i2c-tegra.c 프로젝트: Anjali05/linux
static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
{
	unsigned long timeout = jiffies + HZ;
	unsigned int offset;
	u32 mask, val;

	if (i2c_dev->hw->has_mst_fifo) {
		mask = I2C_MST_FIFO_CONTROL_TX_FLUSH |
		       I2C_MST_FIFO_CONTROL_RX_FLUSH;
		offset = I2C_MST_FIFO_CONTROL;
	} else {
		mask = I2C_FIFO_CONTROL_TX_FLUSH |
		       I2C_FIFO_CONTROL_RX_FLUSH;
		offset = I2C_FIFO_CONTROL;
	}

	val = i2c_readl(i2c_dev, offset);
	val |= mask;
	i2c_writel(i2c_dev, val, offset);

	while (i2c_readl(i2c_dev, offset) & mask) {
		if (time_after(jiffies, timeout)) {
			dev_warn(i2c_dev->dev, "timeout waiting for fifo flush\n");
			return -ETIMEDOUT;
		}
		msleep(1);
	}
	return 0;
}
static inline void rk30_i2c_clean_stop(struct rk30_i2c *i2c)
{
    unsigned int con = i2c_readl(i2c->regs + I2C_CON);

    con &= ~I2C_CON_STOP;
    i2c_writel(con, i2c->regs + I2C_CON);
}
예제 #6
0
파일: i2c-tegra.c 프로젝트: Anjali05/linux
static void tegra_i2c_unmask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
{
	u32 int_mask;

	int_mask = i2c_readl(i2c_dev, I2C_INT_MASK) | mask;
	i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
}
예제 #7
0
static int i2c_jz_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int count)
{
    int i, ret = 0;
    struct i2c_jz *i2c = adap->algo_data;

#ifdef CONFIG_I2C_DEBUG_INFO
    if (i2c->debug > DEBUG_WARN) {
        printk("\n\n\n");
        dev_info(&(i2c->adap.dev),
                 "%s, Begin master xfer, want to transfer msg count is %d\n",
                 __func__, count);
    }
#endif
    clk_enable(i2c->clk);

    i2c_writel(i2c, I2C_TAR, msg->addr);

    for (i = 0; i < count; i++, msg++) {
        enum msg_end_type end_type = MSG_END_STOP;
        if (i < (count - 1)) {
            if (msg[i + 1].flags & I2C_M_NOSTART) {
                end_type = MSG_END_CONTINUE;	/* have no STOP and START */
            } else {
                end_type = MSG_END_REPEAT_START;	/* have no STOP but have RESTART */
            }
        }

        INIT_COMPLETION(i2c->complete);

#ifdef CONFIG_I2C_DEBUG_INFO
        if (i2c->debug > DEBUG_WARN)
            dev_info(&(i2c->adap.dev),
                     "%s, Now transfer msg: %d\n", __func__, i);
#endif
        if (msg->flags & I2C_M_RD) {
            ret = xfer_read(i2c, msg->buf, msg->len, end_type);
        } else {
            ret = xfer_write(i2c, msg->buf, msg->len, end_type);
        }
        if (ret < 0) {
            clk_disable(i2c->clk);
            goto ERR;
        }
    }

    if (i2c_disable_clk(i2c)) {
        ret = -ETIMEDOUT;
        goto ERR;
    }

#ifdef CONFIG_I2C_DEBUG_INFO
    if (i2c->debug > DEBUG_WARN)
        dev_info(&(i2c->adap.dev),
                 "%s, Transfer msg over\n\n\n", __func__);
#endif

ERR:
    return ret ? : i;
}
static inline void rk30_i2c_send_stop(struct rk30_i2c *i2c)
{
    unsigned int con = i2c_readl(i2c->regs + I2C_CON);

    con |= I2C_CON_STOP;
    if(con & I2C_CON_START)
        dev_warn(i2c->dev, "I2C_CON: start bit is set\n");

    i2c_writel(con, i2c->regs + I2C_CON);
}
static inline void rk30_set_rx_mode(struct rk30_i2c *i2c, unsigned int lastnak)
{
    unsigned long con = i2c_readl(i2c->regs + I2C_CON);

    con &= (~I2C_CON_MASK);
    con |= (I2C_CON_MOD_RX << 1);
    if(lastnak)
        con |= I2C_CON_LASTACK;
    i2c_writel(con, i2c->regs + I2C_CON);
}
예제 #10
0
static inline void rk30_i2c_enable(struct rk30_i2c *i2c, unsigned int lastnak)
{
    unsigned int con = 0;

    con |= I2C_CON_EN;
    con |= I2C_CON_MOD(i2c->mode);
    if(lastnak)
        con |= I2C_CON_LASTACK;
    con |= I2C_CON_START;
    i2c_writel(con, i2c->regs + I2C_CON);
}
예제 #11
0
static int i2c_jz_disable(struct i2c_jz *i2c)
{
    int timeout = TIMEOUT;
    i2c_writel(i2c, I2C_ENB, 0);
    while ((i2c_readl(i2c, I2C_ENSTA) & I2C_ENB_I2CENB) && (--timeout > 0))
        msleep(1);

    if (timeout)
        return 0;

    printk("enable i2c%d failed\n", i2c->adap.nr);
    return -ETIMEDOUT;
}
예제 #12
0
static irqreturn_t rk30_i2c_irq(int irq, void *dev_id)
{
    struct rk30_i2c *i2c = dev_id;
    unsigned int ipd;

    spin_lock(&i2c->lock);
    ipd = i2c_readl(i2c->regs + I2C_IPD);
    if(i2c->state == STATE_IDLE) {
        dev_info(i2c->dev, "Addr[0x%02x]  irq in STATE_IDLE, ipd = 0x%x\n", i2c->addr, ipd);
        i2c_writel(I2C_IPD_ALL_CLEAN, i2c->regs + I2C_IPD);
        goto out;
    }

    if(ipd & I2C_NAKRCVIPD) {
        i2c_writel(I2C_NAKRCVIPD, i2c->regs + I2C_IPD);
        i2c->error = -EAGAIN;
        goto out;
    }
    rk30_i2c_irq_nextblock(i2c, ipd);
out:
    spin_unlock(&i2c->lock);
    return IRQ_HANDLED;
}
예제 #13
0
/* SCL Divisor = 8 * (CLKDIVL + CLKDIVH)
 * SCL = i2c_rate/ SCLK Divisor
*/
static void  rk30_i2c_set_clk(struct rk30_i2c *i2c, unsigned long scl_rate)
{
    unsigned long i2c_rate = clk_get_rate(i2c->clk);

    unsigned int div, divl, divh;

    if((scl_rate == i2c->scl_rate) && (i2c_rate == i2c->i2c_rate))
        return;
    i2c->i2c_rate = i2c_rate;
    i2c->scl_rate = scl_rate;
    div = rk30_ceil(i2c_rate, scl_rate * 8);
    divh = divl = rk30_ceil(div, 2);
    i2c_writel(I2C_CLKDIV_VAL(divl, divh), i2c->regs + I2C_CLKDIV);
    i2c_dbg(i2c->dev, "set clk(I2C_CLKDIV: 0x%08x)\n", i2c_readl(i2c->regs + I2C_CLKDIV));
    return;
}
예제 #14
0
static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
{
	unsigned long timeout = jiffies + HZ;
	u32 val = i2c_readl(i2c_dev, I2C_FIFO_CONTROL);
	val |= I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH;
	i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);

	while (i2c_readl(i2c_dev, I2C_FIFO_CONTROL) &
		(I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH)) {
		if (time_after(jiffies, timeout)) {
			dev_warn(i2c_dev->dev, "timeout waiting for fifo flush\n");
			return -ETIMEDOUT;
		}
		msleep(1);
	}
	return 0;
}
예제 #15
0
static void rk30_i2c_stop(struct rk30_i2c *i2c, int ret)
{

    i2c->msg_ptr = 0;
    i2c->msg = NULL;
    if(ret == -EAGAIN) {
        i2c->state = STATE_IDLE;
        i2c->is_busy = 0;
        wake_up(&i2c->wait);
        return;
    }
    i2c->error = ret;
    i2c_writel(I2C_STOPIEN, i2c->regs + I2C_IEN);
    i2c->state = STATE_STOP;
    rk30_i2c_send_stop(i2c);
    return;
}
예제 #16
0
static void rk30_irq_read_prepare(struct rk30_i2c *i2c)
{
    unsigned int cnt, len = i2c->msg->len - i2c->msg_ptr;

    if(len <= 32 && i2c->msg_ptr != 0)
        rk30_set_rx_mode(i2c, 1);
    else if(i2c->msg_ptr != 0)
        rk30_set_rx_mode(i2c, 0);

    if(is_msgend(i2c)) {
        rk30_i2c_stop(i2c, i2c->error);
        return;
    }
    if(len > 32)
        cnt = 32;
    else
        cnt = len;
    i2c_writel(cnt, i2c->regs + I2C_MRXCNT);
}
예제 #17
0
static int i2c_lpc2k_clear_arb(struct lpc2k_i2c *i2c)
{
	long timeout = jiffies + HZ;
	int ret = 0;

	/*
	 * If the transfer needs to abort for some reason, we'll try to
	 * force a stop condition to clear any pending bus conditions
	 */
	i2c_writel(LPC24XX_STO, i2c->reg_base + LPC24XX_I2CONSET);

	/* Wait for status change */
	while (jiffies < timeout &&
		(i2c_readl(i2c->reg_base + LPC24XX_I2STAT) != m_i2c_idle))
		cpu_relax();

	if (i2c_readl(i2c->reg_base + LPC24XX_I2STAT) != m_i2c_idle) {
		/* Bus was not idle, try to reset adapter */
		i2c_lpc2k_reset(i2c);
		ret = -EBUSY;
	}

	return ret;
}
예제 #18
0
/* rk30_i2c_doxfer
 *
 * this starts an i2c transfer
*/
static int rk30_i2c_doxfer(struct rk30_i2c *i2c,
                           struct i2c_msg *msgs, int num)
{
    unsigned long timeout, flags;
    int error = 0;
    /* 32 -- max transfer bytes
     * 2 -- addr bytes * 2
     * 3 -- max reg addr bytes
     * 9 -- cycles per bytes
     * max cycles: (32 + 2 + 3) * 9 --> 400 cycles
     */
    int msleep_time = 400 * 1000/ i2c->scl_rate; // ms

    if (i2c->suspended) {
        dev_err(i2c->dev, "i2c is suspended\n");
        return -EIO;
    }

    spin_lock_irqsave(&i2c->lock, flags);
    if(rk30_i2c_set_master(i2c, msgs, num) < 0) {
        spin_unlock_irqrestore(&i2c->lock, flags);
        dev_err(i2c->dev, "addr[0x%02x] set master error\n", msgs[0].addr);
        return -EIO;
    }
    i2c->addr = msgs[0].addr;
    i2c->msg_ptr = 0;
    i2c->error = 0;
    i2c->is_busy = 1;
    i2c->state = STATE_START;
    i2c->complete_what = 0;
    i2c_writel(I2C_STARTIEN, i2c->regs + I2C_IEN);
    spin_unlock_irqrestore(&i2c->lock, flags);

    rk30_i2c_enable(i2c, (i2c->count > 32)?0:1); //if count > 32,  byte(32) send ack

    if (in_atomic()) {
        int tmo = I2C_WAIT_TIMEOUT * USEC_PER_MSEC;
        while(tmo-- && i2c->is_busy != 0)
            udelay(1);
        timeout = (tmo <= 0)?0:1;
    } else
        timeout = wait_event_timeout(i2c->wait, (i2c->is_busy == 0), msecs_to_jiffies(I2C_WAIT_TIMEOUT));

    spin_lock_irqsave(&i2c->lock, flags);
    i2c->state = STATE_IDLE;
    error = i2c->error;
    spin_unlock_irqrestore(&i2c->lock, flags);

    if (timeout == 0) {
        if(error < 0)
            i2c_dbg(i2c->dev, "error = %d\n", error);
        else if((i2c->complete_what !=COMPLETE_READ  && i2c->complete_what != COMPLETE_WRITE)) {
            dev_err(i2c->dev, "Addr[0x%02x] wait event timeout, state: %d, is_busy: %d, error: %d, complete_what: 0x%x, ipd: 0x%x\n",
                    msgs[0].addr, i2c->state, i2c->is_busy, error, i2c->complete_what, i2c_readl(i2c->regs + I2C_IPD));
            //rk30_show_regs(i2c);
            error = -ETIMEDOUT;
            msleep(msleep_time);
            rk30_i2c_send_stop(i2c);
            msleep(1);
        }
        else
            i2c_dbg(i2c->dev, "Addr[0x%02x] wait event timeout, but transfer complete\n", i2c->addr);
    }
    i2c_writel(I2C_IPD_ALL_CLEAN, i2c->regs + I2C_IPD);
    rk30_i2c_disable_irq(i2c);
    rk30_i2c_disable(i2c);

    if(error == -EAGAIN)
        i2c_dbg(i2c->dev, "No ack(complete_what: 0x%x), Maybe slave(addr: 0x%02x) not exist or abnormal power-on\n",
                i2c->complete_what, i2c->addr);
    return error;
}
예제 #19
0
static int rk30_i2c_set_master(struct rk30_i2c *i2c, struct i2c_msg *msgs, int num)
{
    unsigned int addr = (msgs[0].addr & 0x7f) << 1;
    unsigned int reg_valid_bits = 0;
    unsigned int reg_addr = 0;

    if(num == 1) {
        i2c->count = msgs[0].len;
        if(!(msgs[0].flags & I2C_M_RD)) {
            i2c->msg = &msgs[0];
            i2c->mode = I2C_CON_MOD_TX;
        }
        else {
            addr |= 1;
            i2c->msg = &msgs[0];
            i2c_writel(addr | I2C_MRXADDR_LOW, i2c->regs + I2C_MRXADDR);
            i2c_writel(0, i2c->regs + I2C_MRXRADDR);
            i2c->mode = I2C_CON_MOD_TRX;
            //i2c->mode = I2C_CON_MOD_RX;
        }
    }
    else if(num == 2) {
        i2c->count = msgs[1].len;
        switch(msgs[0].len) {
        case 1:
            reg_addr = msgs[0].buf[0];
            reg_valid_bits |= I2C_MRXADDR_LOW;
            break;
        case 2:
            reg_addr = msgs[0].buf[0] | (msgs[0].buf[1] << 8);
            reg_valid_bits |= I2C_MRXADDR_LOW | I2C_MRXADDR_MID;
            break;
        case 3:
            reg_addr = msgs[0].buf[0] | (msgs[0].buf[1] << 8) | (msgs[0].buf[2] << 16);
            reg_valid_bits |= I2C_MRXADDR_LOW | I2C_MRXADDR_MID | I2C_MRXADDR_HIGH;
            break;
        default:
            return -EIO;
        }
        if((msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD)) {
            addr |= 1;
            i2c->msg = &msgs[1];
            i2c_writel(addr | I2C_MRXADDR_LOW, i2c->regs + I2C_MRXADDR);
            i2c_writel(reg_addr | reg_valid_bits, i2c->regs + I2C_MRXRADDR);
            i2c->mode = I2C_CON_MOD_RRX;
        }
        else if(!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD)) {
            i2c->msg = &msgs[1];
            i2c_writel(addr | I2C_MRXADDR_LOW, i2c->regs + I2C_MRXADDR);
            i2c_writel(reg_addr | reg_valid_bits, i2c->regs + I2C_MRXRADDR);
            i2c->mode = I2C_CON_MOD_TRX;
        }
        else
            return -EIO;
    }
    else {
        dev_err(i2c->dev, "This case(num > 2) has not been support now\n");
        return -EIO;
    }

    return 0;
}
예제 #20
0
static inline int xfer_write(struct i2c_jz *i2c, unsigned char *buf, int len,
                             enum msg_end_type end_type)
{
    int ret = 0;
    long timeout = TIMEOUT;
    unsigned short reg_tmp;
    unsigned int wait_complete_timeout_ms;

    wait_complete_timeout_ms =
        len * 1000 * 9 * 2 / i2c->rate + CONFIG_I2C_JZV10_WAIT_MS;

#ifdef CONFIG_I2C_DEBUG_INFO
    if (i2c->debug > DEBUG_WARN)
        dev_info(&(i2c->adap.dev),
                 "%s, Begin write msg, want to write length is %d\n",
                 __func__, len);
#endif

    i2c->wbuf = buf;
    i2c->len = len;

    i2c_writel(i2c, I2C_TXTL, TX_LEVEL);

    i2c_readl(i2c, I2C_CSTP);	/* clear STP bit */
    i2c_readl(i2c, I2C_CTXOF);	/* clear TXOF bit */
    i2c_readl(i2c, I2C_CTXABRT);	/* clear TXABRT bit */

    i2c->w_end_type = end_type;
    while ((i2c_readl(i2c, I2C_STA) & I2C_STA_TFNF) && (i2c->len > 0)) {
        reg_tmp = *i2c->wbuf++;
        if (i2c->len == 1) {
            if (end_type == MSG_END_STOP) {
                reg_tmp |= I2C_DC_STP;
            }
        }
        i2c_writel(i2c, I2C_DC, reg_tmp);

        i2c->len -= 1;
    }

    if (i2c->len == 0) {
        i2c_writel(i2c, I2C_TXTL, 0);
    }

    reg_tmp = I2C_INTM_MTXEMP | I2C_INTM_MTXABT | I2C_INTM_MTXOF;
    if (end_type == MSG_END_STOP)
        reg_tmp |= I2C_INTM_MISTP;

    i2c_writel(i2c, I2C_INTM, reg_tmp);

    timeout = wait_for_completion_timeout(&i2c->complete,
                                          msecs_to_jiffies
                                          (wait_complete_timeout_ms));

    if (!timeout) {
        dev_err(&(i2c->adap.dev), "--I2C pio write wait timeout\n");
#ifdef I2C_DEBUG
        i2c_jz_dump_regs(i2c);
#endif
        ret = -ETIMEDOUT;
    }

    reg_tmp = i2c_readl(i2c, I2C_TXABRT);
    if (reg_tmp) {
        txabrt(i2c, reg_tmp);
        if (reg_tmp > 0x1 && reg_tmp < 0x10)
            ret = -ENXIO;
        else
            ret = -EIO;
        //after I2C_TXABRT_ABRT_XDATA_NOACK error,this required core to resend
        if (reg_tmp & 8) {
            ret = -EAGAIN;
        }
        i2c_readl(i2c, I2C_CTXABRT);
    }

    if (ret < 0)
        i2c_jz_reset(i2c);

#ifdef CONFIG_I2C_DEBUG_INFO
    if (i2c->debug > DEBUG_WARN)
        dev_info(&(i2c->adap.dev),
                 "%s, Write msg over\n", __func__);
#endif
    return ret;
}
예제 #21
0
static void rk30_i2c_irq_nextblock(struct rk30_i2c *i2c, unsigned int ipd)
{
    switch (i2c->state) {
    case STATE_START:
        if(!(ipd & I2C_STARTIPD)) {
            rk30_i2c_stop(i2c, -ENXIO);
            dev_err(i2c->dev, "Addr[0x%02x] no start irq in STATE_START\n", i2c->addr);
            rk30_show_regs(i2c);
            i2c_writel(I2C_IPD_ALL_CLEAN, i2c->regs + I2C_IPD);
            goto out;
        }
        i2c->complete_what |= 1<<i2c->state;
        i2c_writel(I2C_STARTIPD, i2c->regs + I2C_IPD);
        rk30_i2c_clean_start(i2c);
        if(i2c->mode ==  I2C_CON_MOD_TX) {
            i2c_writel(I2C_MBTFIEN  | I2C_NAKRCVIEN, i2c->regs + I2C_IEN);
            i2c->state = STATE_WRITE;
            goto prepare_write;
        } else {
            i2c_writel(I2C_MBRFIEN | I2C_NAKRCVIEN, i2c->regs + I2C_IEN);
            i2c->state = STATE_READ;
            goto prepare_read;
        }
    case STATE_WRITE:
        if(!(ipd & I2C_MBTFIPD)) {
            rk30_i2c_stop(i2c, -ENXIO);
            dev_err(i2c->dev, "Addr[0x%02x] no mbtf irq in STATE_WRITE\n", i2c->addr);
            rk30_show_regs(i2c);
            i2c_writel(I2C_IPD_ALL_CLEAN, i2c->regs + I2C_IPD);
            goto out;
        }
        i2c->complete_what |= 1<<i2c->state;
        i2c_writel(I2C_MBTFIPD, i2c->regs + I2C_IPD);
prepare_write:
        rk30_irq_write_prepare(i2c);
        break;
    case STATE_READ:
        if(!(ipd & I2C_MBRFIPD)) {
            rk30_i2c_stop(i2c, -ENXIO);
            dev_err(i2c->dev, "Addr[0x%02x] no mbrf irq in STATE_READ, ipd = 0x%x\n", i2c->addr, ipd);
            rk30_show_regs(i2c);
            i2c_writel(I2C_IPD_ALL_CLEAN, i2c->regs + I2C_IPD);
            goto out;
        }
        i2c->complete_what |= 1<<i2c->state;
        i2c_writel(I2C_MBRFIPD, i2c->regs + I2C_IPD);
        rk30_irq_read_get_data(i2c);
prepare_read:
        rk30_irq_read_prepare(i2c);
        break;
    case STATE_STOP:
        if(!(ipd & I2C_STOPIPD)) {
            rk30_i2c_stop(i2c, -ENXIO);
            dev_err(i2c->dev, "Addr[0x%02x] no stop irq in STATE_STOP\n", i2c->addr);
            rk30_show_regs(i2c);
            i2c_writel(I2C_IPD_ALL_CLEAN, i2c->regs + I2C_IPD);
            goto out;
        }
        rk30_i2c_clean_stop(i2c);
        i2c_writel(I2C_STOPIPD, i2c->regs + I2C_IPD);
        i2c->is_busy = 0;
        i2c->complete_what |= 1<<i2c->state;
        i2c->state = STATE_IDLE;
        wake_up(&i2c->wait);
        break;
    default:
        break;
    }
out:
    return;
}
예제 #22
0
static int i2c_set_speed(struct i2c_jz *i2c, int rate)
{
    /*ns */
    long dev_clk = clk_get_rate(i2c->clk);
    long cnt_high = 0;	/* HIGH period count of the SCL clock */
    long cnt_low = 0;	/* LOW period count of the SCL clock */
    long setup_time = 0;
    long hold_time = 0;
    unsigned short tmp;

    i2c->rate = rate;
    if (i2c_jz_disable(i2c))
        dev_info(&(i2c->adap.dev), "i2c not disable\n");
    if (rate <= 100000) {
        tmp = 0x43 | (1 << 5);	/* standard speed mode */
        i2c_writel(i2c, I2C_CTRL, tmp);
    } else {
        tmp = 0x45 | (1 << 5);	/* fast speed mode */
        i2c_writel(i2c, I2C_CTRL, tmp);
    }

    /*         high
     *         ____     ____      ____      ____
     *  clk __|  | |___|    |____|    |____|    |___
     *           | | |
     *           | | |
     *           |_|_|     _________      ____
     * data    __/ | |\___/         \____/    \____
     *    setup->| |<|
     *           ->| |<-hold
     */

    //setup_time = (10 000 000/(rate*4)) + 1;
    setup_time = (dev_clk / (rate * 4));
    if (setup_time > 1)
        setup_time -= 1;
    //hold_time =  (10000000/(rate*4)) - 1;
    hold_time = (dev_clk / (rate * 4));

    /*         high
     *         ____     ____
     *  clk __|    |___|    |____
     *              low
     *        |<--period--->|
     *
     */
    cnt_high = dev_clk / (rate * 2);
    cnt_low = dev_clk / (rate * 2);

    dev_info(&(i2c->adap.dev), "set:%ld  hold:%ld dev=%ld h=%ld l=%ld\n",
             setup_time, hold_time, dev_clk, cnt_high, cnt_low);
    if (setup_time > 255)
        setup_time = 255;
    if (setup_time <= 0)
        setup_time = 1;
    if (hold_time > 0xFFFF)
        hold_time = 0xFFFF;

    if (rate <= 100000) {
        i2c_writel(i2c, I2C_SHCNT, I2CSHCNT_ADJUST(cnt_high));
        i2c_writel(i2c, I2C_SLCNT, I2CSLCNT_ADJUST(cnt_low));
    } else {
        i2c_writel(i2c, I2C_FHCNT, I2CFHCNT_ADJUST(cnt_high));
        i2c_writel(i2c, I2C_FLCNT, I2CFLCNT_ADJUST(cnt_low));
    }

    i2c_writel(i2c, I2C_SDASU, setup_time & 0xff);
    i2c_writel(i2c, I2C_SDAHD, hold_time);

    return 0;
}
예제 #23
0
static int i2c_jz_probe(struct platform_device *dev)
{
    int ret = 0;
    struct i2c_jz *i2c;
    struct resource *res;
    unsigned int reg_tmp;

    i2c = kzalloc(sizeof(struct i2c_jz), GFP_KERNEL);
    if (!i2c) {
        printk("Error: Now we can not malloc memory for I2C!\n");
        ret = -ENOMEM;
        goto ERR0;
    }

    i2c->adap.owner = THIS_MODULE;
    i2c->adap.algo = &i2c_jz_algorithm;
    i2c->adap.retries = 5;
    i2c->adap.timeout = 5;
    i2c->adap.algo_data = i2c;
    i2c->adap.dev.parent = &dev->dev;
    i2c->adap.nr = dev->id;
    sprintf(i2c->adap.name, "i2c%u", dev->id);

    i2c->clk = clk_get(&dev->dev, i2c->adap.name);
    if (!i2c->clk) {
        printk("Error: Now we can not get i2c%d clock!\n", dev->id);
        ret = -ENODEV;
        goto clk_failed;
    }

    res = platform_get_resource(dev, IORESOURCE_MEM, 0);
    i2c->iomem = ioremap(res->start, resource_size(res));
    if (!i2c->iomem) {
        printk("Error: Now we can remap IO for I2C%d!\n", dev->id);
        ret = -ENOMEM;
        goto io_failed;
    }

    i2c->irq = platform_get_irq(dev, 0);
    ret =
        request_irq(i2c->irq, i2c_jz_irq, IRQF_DISABLED,
                    dev_name(&dev->dev), i2c);
    if (ret) {
        printk("Error: Now we can request irq for I2C%d!\n", dev->id);
        ret = -ENODEV;
        goto irq_failed;
    }

    clk_enable(i2c->clk);

    res = platform_get_resource(dev, IORESOURCE_BUS, 0);

    i2c_set_speed(i2c, res->start * 1000);

#if 0
    reg_tmp = i2c_readl(i2c, I2C_DC);
    reg_tmp &= ~I2C_DC_STP;
    i2c_writel(i2c, I2C_DC, reg_tmp);
#endif

    reg_tmp = i2c_readl(i2c, I2C_CTRL);
    reg_tmp |= I2C_CTRL_REST;
    i2c_writel(i2c, I2C_CTRL, reg_tmp);

    // for jgao WHY?
    //  i2c_writel(i2c, I2C_FLT, 0xF);      /*set filter*/

    i2c_writel(i2c, I2C_INTM, 0x0);

    init_completion(&i2c->complete);

    ret = i2c_add_numbered_adapter(&i2c->adap);
    if (ret < 0) {
        dev_err(&(i2c->adap.dev), KERN_INFO "I2C: Failed to add bus\n");
        goto adapt_failed;
    }

    platform_set_drvdata(dev, i2c);

    i2c_jz_enable(i2c);

    clk_disable(i2c->clk);

#ifdef CONFIG_I2C_DEBUG_INFO
    ret = create_debug_sysfs_interface(&dev->dev);
    if (ret < 0)
        dev_err(&i2c->adap.dev, "create debug sysfs interface failed\n");
#endif

    return 0;

adapt_failed:
    free_irq(i2c->irq, i2c);
irq_failed:
    iounmap(i2c->iomem);
io_failed:
    clk_put(i2c->clk);
clk_failed:
    kfree(i2c);
ERR0:
    return ret;
}
예제 #24
0
int __init i2c_61_init(void)
{
    int rc = 0;
    int i2c_clk = 0;
    int gcr_kdv;
    unsigned long gcr;
	printk(KERN_INFO "Initialize Prolific I2C adapter module v%s\n", VERSION);

    i2c_adapt_data.base = DEFAULT_BASE;
    i2c_adapt_data.irq = DEFAULT_IRQ;
    i2c_adapt_data.clock = DEFAULT_CLOCK;
    i2c_adapt_data.own = DEFAULT_OWN;
	i2c_algo_data.data = (void *)&i2c_adapt_data;
	init_waitqueue_head(&i2c_adapt_data.i2c_wait);
    atomic_set(&i2c_adapt_data.irq_done, 0);


    if (i2c_clk_setup) {
        i2c_cd = i2c_cd & 0x7;
        writeb(i2c_cd, PL_CLK_I2C);
        i2c_clk = pl_get_dev_hz() / 8;  /* jedy should be modified */
        gcr_kdv = i2c_kdv;
    } else if (pl_get_dev_hz() == 96000000) {   /* dclk = 96MHz */
        writeb(6, PL_CLK_I2C);                  /* program i2c dev clk to 24MHz */
        gcr_kdv = 10;            /* program i2c data rate = i2c_dev_clk/(20*(10+2)) */
        i2c_clk = 96000000/4;
    } else if (pl_get_dev_hz() == 32000000) {    /* dclk = 32MHz */
        writeb(5, PL_CLK_I2C);                   /* target 16MHz */
        gcr_kdv = 6;
        i2c_clk = 32000000/2;
    } else if (pl_get_dev_hz() == 120000000) {  /* dclk = 120MHz */
        writeb(6, PL_CLK_I2C);                  /* program i2c dev clk to 30MHz */
        gcr_kdv = 13;
        i2c_clk = 120000000/4;
    } else {
        writeb(7, PL_CLK_I2C);
        gcr_kdv = 32;
        i2c_clk = pl_get_dev_hz()/8;
    }

    i2c_adapt_data.clock = i2c_clk / (20 * (gcr_kdv + 2));

#if 0
    gcr = PL_GCR_I2CEN | PL_GCR_MCR_IEN | PL_GCR_SCR_IEN | PL_GCR_KDV(gcr_kdv) |
            PL_GCR_XSCL_PU | PL_GCR_XSCL_6MA |  PL_GCR_XSDA_PU | PL_GCR_XSDA_6MA;
#endif
    gcr = PL_GCR_I2CEN | PL_GCR_MCR_IEN | PL_GCR_KDV(gcr_kdv);
    i2c_writel(&i2c_adapt_data, I2C_GCR, gcr);

    rc = request_irq(i2c_adapt_data.irq, i2c_handler, 0, "I2C ADAPT", &i2c_adapt_data);
    if (rc < 0) {
        printk("Failed to enable i2c irq %d\n", i2c_adapt_data.irq);
        rc = -ENODEV;
        goto EXIT;
    }
    /* enable_irq(i2c_adapt_data.irq); */  // it's redundant

    init_timer(&i2c_adapt_data.wait_timeout);
    i2c_adapt_data.wait_timeout.function = i2c_timeout_handler;
    i2c_adapt_data.wait_timeout.data = (unsigned long) &i2c_adapt_data;



    if (i2c_61_add_bus(&i2c_61_ops) < 0) {
        rc = -ENODEV;
        goto EXIT;
    }
	printk(KERN_INFO " found i2c adapter at %#x irq %d. Data tranfer clock is %dHz\n",
		i2c_adapt_data.base, i2c_adapt_data.irq, i2c_adapt_data.clock);


EXIT:
    return rc;
}
예제 #25
0
static inline void rk30_i2c_enable_irq(struct rk30_i2c *i2c)
{
    i2c_writel(IRQ_MST_ENABLE, i2c->regs + I2C_IEN);
}
예제 #26
0
static inline void rk30_i2c_disable_irq(struct rk30_i2c *i2c)
{
    i2c_writel(IRQ_ALL_DISABLE, i2c->regs + I2C_IEN);
}
예제 #27
0
static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
{
	unsigned long status;
	unsigned char data;

	/*
	 * I2C in the LPC2xxx series is basically a state machine.
	 * Just run through the steps based on the current status.
	 */
	status = i2c_readl(i2c->reg_base + LPC24XX_I2STAT);

	switch (status) {
	case m_start:
	case m_repstart:
		/* Start bit was just sent out, send out addr and dir */
		data = (i2c->msg->addr << 1);
		if (i2c->msg->flags & I2C_M_RD)
			data |= 1;

		i2c_writel((unsigned long) data,
			i2c->reg_base + LPC24XX_I2DAT);
		i2c_writel(LPC24XX_STA,
			i2c->reg_base + LPC24XX_I2CONCLR);

		dev_dbg(&i2c->adap.dev, "Start sent, sending address "
			"0x%02x\n", data);
		break;

	case mx_addr_w_ack:
	case mx_data_w_ack:
		/*
		 * Address or data was sent out with an ACK. If there is more
		 * data to send, send it now
		 */
		if (i2c->msg_idx < i2c->msg->len) {
			i2c_writel((unsigned long)
				i2c->msg->buf[i2c->msg_idx],
				i2c->reg_base + LPC24XX_I2DAT);
			dev_dbg(&i2c->adap.dev, "ACK ok, sending "
				"(0x%02x)\n", i2c->msg->buf[i2c->msg_idx]);
		} else if (i2c->is_last) {
			/* Last message, send stop */
			i2c_writel(LPC24XX_STO | LPC24XX_AA,
				i2c->reg_base + LPC24XX_I2CONSET);
			i2c_writel(LPC24XX_SI, i2c->reg_base + LPC24XX_I2CONCLR);
			i2c->msg_status = 0;
			dev_dbg(&i2c->adap.dev, "ACK ok, sending stop\n");
			disable_irq_nosync(i2c->irq);
		} else {
			i2c->msg_status = 0;
			dev_dbg(&i2c->adap.dev, "ACK ok, idling until "
				"next message start\n");
			disable_irq_nosync(i2c->irq);
		}

		i2c->msg_idx++;
		break;

	case mr_addr_r_ack:
		/*
		 * Receive first byte from slave
		 */
		if (i2c->msg->len == 1) {
			/* Last byte, return NACK */
			i2c_writel(LPC24XX_AA,
				i2c->reg_base + LPC24XX_I2CONCLR);
		} else {
			/* Not last byte, return ACK */
			i2c_writel(LPC24XX_AA,
				i2c->reg_base + LPC24XX_I2CONSET);
		}

		i2c_writel(LPC24XX_STA, i2c->reg_base + LPC24XX_I2CONCLR);
		break;

	case mr_data_r_nack:
		/*
		 * The I2C shows NACK status on reads, so we need to accept
		 * the NACK as an ACK here. This should be ok, as the real
		 * BACK would of been caught on the address write.
		 */
	case mr_data_r_ack:
		/*
		 * Data was received
		 */
		if (i2c->msg_idx < i2c->msg->len) {
			i2c->msg->buf[i2c->msg_idx] =
				i2c_readl(i2c->reg_base + LPC24XX_I2DAT);
			dev_dbg(&i2c->adap.dev, "ACK ok, received "
				"(0x%02x)\n", i2c->msg->buf[i2c->msg_idx]);
		}

		/*
		 * If transfer is done, send STOP
		 */
		if (i2c->msg_idx >= i2c->msg->len - 1 && i2c->is_last) {
			i2c_writel(LPC24XX_STO | LPC24XX_AA,
				i2c->reg_base + LPC24XX_I2CONSET);
			i2c_writel(LPC24XX_SI, i2c->reg_base + LPC24XX_I2CONCLR);
			i2c->msg_status = 0;
			dev_dbg(&i2c->adap.dev, "ACK ok, sending stop\n");
		}

		/*
		 * Message is done
		 */
		if (i2c->msg_idx >= i2c->msg->len - 1) {
			i2c->msg_status = 0;
			dev_dbg(&i2c->adap.dev, "ACK ok, idling until "
				"next message start\n");
			disable_irq_nosync(i2c->irq);
		}

		/*
		 * One pre-last data input, send NACK to tell the slave that
		 * this is going to be the last data byte to be transferred.
		 */
		if (i2c->msg_idx >= i2c->msg->len - 2) {
			/* One byte left to receive - NACK */
			i2c_writel(LPC24XX_AA,
				i2c->reg_base + LPC24XX_I2CONCLR);
		} else {
			/* More than one byte left to receive - ACK */
			i2c_writel(LPC24XX_AA,
				i2c->reg_base + LPC24XX_I2CONSET);
		}

		i2c_writel(LPC24XX_STA,
			i2c->reg_base + LPC24XX_I2CONCLR);
		i2c->msg_idx++;
		break;

	case mx_addr_w_nack:
	case mx_data_w_nack:
	case mr_addr_r_nack:
		/*
		 * NACK! Processing is done
		 */
		i2c_writel(LPC24XX_STO | LPC24XX_AA,
			i2c->reg_base + LPC24XX_I2CONSET);
		i2c->msg_status = -ENODEV;
		dev_dbg(&i2c->adap.dev, "Device NACKed, error\n");
		disable_irq_nosync(i2c->irq);
		break;

	case m_data_arb_lost:
		/*
		 * Arbitration lost
		 */
		i2c->msg_status = -EIO;
		dev_dbg(&i2c->adap.dev, "Arbitration lost, error\n");

		/*
		 * Release the I2C bus
		 */
		i2c_writel(LPC24XX_STA | LPC24XX_STO,
			i2c->reg_base + LPC24XX_I2CONCLR);
		disable_irq_nosync(i2c->irq);
		break;

	default:
		/* Unexpected statuses */
		i2c->msg_status = -EIO;
		dev_err(&i2c->adap.dev, "Unexpected status, error (%x)\n",
			(unsigned int) status);
		disable_irq_nosync(i2c->irq);
		break;
	}

	/* Exit on failure or all bytes transferred */
	if (i2c->msg_status != -EBUSY)
		wake_up(&i2c->wait);

	/*
	 * If `msg_status` is zero, then `lpc2k_process_msg()` is responsible
	 * for clearing the SI flag.
	 */
	if (i2c->msg_status != 0)
		i2c_writel(LPC24XX_SI, i2c->reg_base + LPC24XX_I2CONCLR);
}
예제 #28
0
static inline void rk30_i2c_disable(struct rk30_i2c *i2c)
{
    i2c_writel( 0, i2c->regs + I2C_CON);
}
예제 #29
0
static int lpc2k_process_msg(struct lpc2k_i2c *i2c, int msgidx)
{
	int ret;

	dev_dbg(&i2c->adap.dev, "Processing message %d (len=%d) (flags=%x)\n",
		msgidx, i2c->msg->len, i2c->msg->flags);

	/*
	 * A new transfer is kicked off by initiating a start condition
	 */
	if (!msgidx) {
		dev_dbg(&i2c->adap.dev, "Start sent\n");
		i2c_writel(LPC24XX_STA, i2c->reg_base + LPC24XX_I2CONSET);
	} else {
		/*
		 * A multi-message I2C transfer continues where the previous
		 * I2C transfer left off and uses the current condition of the
		 * I2C adapter.
		 */
		if (unlikely(i2c->msg->flags & I2C_M_NOSTART)) {
			WARN_ON(i2c->msg->len == 0);

			if (!(i2c->msg->flags & I2C_M_RD)) {
				/* Start transmit of data */
				i2c_writel((unsigned long) i2c->msg->buf[0],
					i2c->reg_base + LPC24XX_I2DAT);
				i2c->msg_idx++;
				dev_dbg(&i2c->adap.dev, "New data sent\n");
			}
			else
				dev_dbg(&i2c->adap.dev, "New data incoming\n");
		} else {
			/* Start or repeated start */
			dev_dbg(&i2c->adap.dev, "Repeated start sent\n");
			i2c_writel(LPC24XX_STA,
				i2c->reg_base + LPC24XX_I2CONSET);
		}

		i2c_writel(LPC24XX_SI,
			i2c->reg_base + LPC24XX_I2CONCLR);
	}

	enable_irq(i2c->irq);

	/* Wait for transfer completion */
	if (wait_event_timeout(i2c->wait, i2c->msg_status != -EBUSY,
		HZ) == 0) {
		disable_irq_nosync(i2c->irq);
		dev_dbg(&i2c->adap.dev, "Transfer timed out!\n");
		ret = -ETIMEDOUT;
	} else {
		ret = i2c->msg_status;
		if (ret == 0)
			dev_dbg(&i2c->adap.dev, "Transfer successful\n");
		else
			dev_dbg(&i2c->adap.dev, "Transfer failed (%d)\n",
				ret);
	}

	return ret;
}
예제 #30
0
static int i2c_lpc2k_probe(struct platform_device *dev)
{
	struct lpc2k_i2c *i2c;
	struct resource *res;
	int ret, irq;
	unsigned long clkrate;

	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(dev, 0);
	if (res == NULL || irq < 0) {
		dev_err(&dev->dev, "No resource data!\n");
		return -ENODEV;
	}

	if (dev->id < 0 || dev->id >= LPC24XX_MAX_ADAPTERS) {
		dev_err(&dev->dev, "I2C bus number invalid (%d)\n", dev->id);
		return -ENODEV;
	}

	if (!request_mem_region(res->start, resource_size(res), res->name)) {
		dev_err(&dev->dev, "Memory region already used!\n");
		return -ENOMEM;
	}

	i2c = kzalloc(sizeof(struct lpc2k_i2c), GFP_KERNEL);
	if (!i2c) {
		dev_err(&dev->dev, "Error allocating memory!\n");
		ret = -ENOMEM;
		goto emalloc;
	}

	i2c->adap.owner = THIS_MODULE;

	init_waitqueue_head(&i2c->wait);

	i2c->adap.nr = dev->id;
	snprintf(i2c->adap.name, sizeof(i2c->adap.name), MODULE_NAME ".%u",
		 i2c->adap.nr);

	i2c->clk = clk_get(&dev->dev, NULL);
	if (IS_ERR(i2c->clk)) {
		dev_err(&dev->dev, "Error getting clock!\n");
		ret = PTR_ERR(i2c->clk);
		goto eclk;
	}

	i2c->reg_base = ioremap(res->start, resource_size(res));
	if (!i2c->reg_base) {
		dev_err(&dev->dev, "Error mapping memory!\n");
		ret = -EIO;
		goto eremap;
	}
	i2c->iobase = res->start;
	i2c->iosize = resource_size(res);
	i2c->irq = irq;

	clk_enable(i2c->clk);

	i2c->adap.algo = &i2c_lpc2k_algorithm;
	ret = request_irq(irq, i2c_lpc2k_handler, IRQF_DISABLED,
		i2c->adap.name, i2c);
	if (ret)
		goto ereqirq;

	disable_irq_nosync(irq);

	i2c_lpc2k_reset(i2c);

	i2c->adap.algo_data = i2c;
	i2c->adap.dev.parent = &dev->dev;

	ret = i2c_add_numbered_adapter(&i2c->adap);
	if (ret < 0) {
		dev_err(&dev->dev, "Failed to add bus!\n");
		goto eadapt;
	}

	platform_set_drvdata(dev, i2c);

	printk(KERN_INFO "I2C: %s: LPC2K I2C adapter\n",
	       dev_name(&i2c->adap.dev));

	/* Place controller is a known state */
	i2c_lpc2k_reset(i2c);

	/* Get I2C base clock rate */
	clkrate = clk_get_rate(i2c->clk);
	if (!clkrate) {
		dev_warn(&dev->dev, "Can't get I2C base clock, using "
			"12MHz!\n");
		clkrate = 12000000;
	}

	/* Setup I2C dividers to generate clock rate with 50% duty cycle */
	clkrate = (clkrate / scl_frequency) / 2;
	i2c_writel(clkrate, i2c->reg_base + LPC24XX_I2SCLL);
	i2c_writel(clkrate, i2c->reg_base + LPC24XX_I2SCLH);

	return 0;

eadapt:
	free_irq(irq, i2c);
ereqirq:
	clk_disable(i2c->clk);
	iounmap(i2c->reg_base);
eremap:
	clk_put(i2c->clk);
eclk:
	kfree(i2c);
emalloc:
	release_mem_region(res->start, resource_size(res));
	return ret;
}