示例#1
0
/*
 * Prepare controller for a transaction and call i2c_davinci_xfer_msg
 */
static int
i2c_davinci_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], int num)
{
	struct davinci_i2c_dev *dev = bus->priv;
	int i;
	int ret;

	i2c_dbg("%s: msgs: %d\n", __func__, num);

	ret = i2c_davinci_wait_bus_not_busy(dev, 1);
	if (ret < 0)
	{
		i2c_dbg("timeout waiting for bus ready\n");
		return ret;
	}

	for (i = 0; i < num; i++)
	{
		ret = i2c_davinci_xfer_msg(bus, &msgs[i], (i == (num - 1)));
		i2c_dbg("%s [%d/%d] ret: %d\n", __func__, i + 1, num,
			ret);
		if (ret < 0)
			return ret;
	}


	return num;
}
示例#2
0
rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
                          struct rt_i2c_msg         msgs[],
                          rt_uint32_t               num)
{
    rt_size_t ret;

    if (bus->ops->master_xfer)
    {
#ifdef RT_I2C_DEBUG
        for (ret = 0; ret < num; ret++)
        {
            i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d%s\n", ret,
                    (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W',
                    msgs[ret].addr, msgs[ret].len);
        }
#endif

        rt_mutex_take(&bus->lock, RT_WAITING_FOREVER);
        ret = bus->ops->master_xfer(bus, msgs, num);
        rt_mutex_release(&bus->lock);

        return ret;
    }
    else
    {
        i2c_dbg("I2C bus operation not supported\n");

        return 0;
    }
}
示例#3
0
/*
 * 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.
 */
static int i2c_davinci_init(struct davinci_i2c_dev *dev)
{
	/* put I2C into reset */
	davinci_i2c_reset_ctrl(dev, 0);

	/* compute clock dividers */
	i2c_davinci_calc_clk_dividers(dev);

	/* Respond at reserved "SMBus Host" slave address" (and zero);
	 * we seem to have no option to not respond...
	 */
	davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08);

	i2c_dbg("PSC  = %d\n",
		davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG));
	i2c_dbg("CLKL = %d\n",
		davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKL_REG));
	i2c_dbg("CLKH = %d\n",
		davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKH_REG));
	i2c_dbg("bus_freq = %dkHz, bus_delay = %d\n",
		dev->bus_freq, dev->bus_delay);

	/* Take the I2C module out of reset: */
	davinci_i2c_reset_ctrl(dev, 1);

	/* Enable interrupts */
	davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL);

	return 0;
}
static int rk30_i2c_xfer(struct i2c_adapter *adap,
			struct i2c_msg *msgs, int num)
{
	int ret = 0, state, retry = 10;
        unsigned long scl_rate;
	struct rk30_i2c *i2c = (struct rk30_i2c *)adap->algo_data;

        clk_enable(i2c->clk);
#ifdef I2C_CHECK_IDLE
printk("wax->%d\n",__LINE__);  //add by nition for test
        while(retry-- && ((state = rk30_i2c_check_idle(i2c)) != I2C_IDLE)){
printk("wax->%d\n",__LINE__); //add by nition for test
                msleep(10);
printk("wax->%d\n",__LINE__); //add by nition for test
        }
printk("wax->%d\n",__LINE__); //add by nition for test
        if(retry == 0){
printk("wax->%d\n",__LINE__); //add by nition for test
                dev_err(i2c->dev, "i2c is not in idle(state = %d)\n", state);
                return -EIO;
        }
#endif

        if(msgs[0].scl_rate <= 400000 && msgs[0].scl_rate >= 10000)
		scl_rate = msgs[0].scl_rate;
	else if(msgs[0].scl_rate > 400000){
		dev_warn(i2c->dev, "Warning: addr[0x%x] msg[0].scl_rate( = %dKhz) is too high!",
			msgs[0].addr, msgs[0].scl_rate/1000);
		scl_rate = 400000;	
	}
	else{
		dev_warn(i2c->dev, "Warning: addr[0x%x] msg[0].scl_rate( = %dKhz) is too low!",
			msgs[0].addr, msgs[0].scl_rate/1000);
		scl_rate = 10000;
	}
        if(i2c->is_div_from_arm[i2c->adap.nr]){
                mutex_lock(&i2c->m_lock);
        }

	rk30_i2c_set_clk(i2c, scl_rate);
        i2c_dbg(i2c->dev, "i2c transfer start: addr: 0x%x, scl_reate: %ldKhz, len: %d\n", msgs[0].addr, scl_rate/1000, num);
	ret = rk30_i2c_doxfer(i2c, msgs, num);
        i2c_dbg(i2c->dev, "i2c transfer stop: addr: 0x%x, state: %d, ret: %d\n", msgs[0].addr, ret, i2c->state);

        if(i2c->is_div_from_arm[i2c->adap.nr]){
                mutex_unlock(&i2c->m_lock);
        }

        clk_disable(i2c->clk);
	return (ret < 0)?ret:num;
}
示例#5
0
/* set i2c bus scl rate */
static void  rk29_i2c_clockrate(struct rk29_i2c_data *i2c)
{

	struct rk29_i2c_platform_data *pdata = i2c->dev->platform_data;
	unsigned int rem = 0, exp = 0;
	unsigned long scl_rate, real_rate = 0, tmp;

	i2c->i2c_rate = clk_get_rate(i2c->clk);

	scl_rate = (i2c->scl_rate) ? i2c->scl_rate : ((pdata->scl_rate)? pdata->scl_rate:100000);

	rk29_i2c_calcdivisor(i2c->i2c_rate, scl_rate, &real_rate, &rem, &exp);

	tmp = readl(i2c->regs + I2C_OPR);
	tmp &= ~0x3f;
	tmp |= exp;
	tmp |= rem<<I2CCDVR_EXP_BITS;	
	writel(tmp, i2c->regs + I2C_OPR);
	if(real_rate > 400000)
		dev_warn(i2c->dev, "i2c_rate[%luKhz], scl_rate[%luKhz], real_rate[%luKhz] > 400Khz\n", 
				i2c->i2c_rate/1000, scl_rate/1000, real_rate/1000);
	else
		i2c_dbg(i2c->dev, "i2c_rate[%luKhz], scl_rate[%luKhz], real_rate[%luKhz]\n", 
				i2c->i2c_rate/1000, scl_rate/1000, real_rate/1000);
	return;
}
示例#6
0
static inline int i2c_send_byte(struct saa7134_dev *dev,
				enum i2c_attr attr,
				unsigned char data)
{
	enum i2c_status status;
	__u32 dword;

	/* have to write both attr + data in one 32bit word */
	dword  = saa_readl(SAA7134_I2C_ATTR_STATUS >> 2);
	dword &= 0x0f;
	dword |= (attr << 6);
	dword |= ((__u32)data << 8);
	dword |= 0x00 << 16;  /* 100 kHz */
//	dword |= 0x40 << 16;  /* 400 kHz */
	dword |= 0xf0 << 24;
	saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);
	i2c_dbg(2, "i2c data => 0x%x\n", data);

	if (!i2c_is_busy_wait(dev))
		return -EIO;
	status = i2c_get_status(dev);
	if (i2c_is_error(status))
		return -EIO;
	return 0;
}
示例#7
0
static int i2c_reset(struct saa7134_dev *dev)
{
	enum i2c_status status;
	int count;

	i2c_dbg(2, "i2c reset\n");
	status = i2c_get_status(dev);
	if (!i2c_is_error(status))
		return true;
	i2c_set_status(dev,status);

	for (count = 0; count < I2C_WAIT_RETRY; count++) {
		status = i2c_get_status(dev);
		if (!i2c_is_error(status))
			break;
		udelay(I2C_WAIT_DELAY);
	}
	if (I2C_WAIT_RETRY == count)
		return false;

	if (!i2c_is_idle(status))
		return false;

	i2c_set_attr(dev,NOP);
	return true;
}
示例#8
0
static inline enum i2c_status i2c_get_status(struct saa7134_dev *dev)
{
	enum i2c_status status;

	status = saa_readb(SAA7134_I2C_ATTR_STATUS) & 0x0f;
	i2c_dbg(2, "i2c stat <= %s\n", str_i2c_status[status]);
	return status;
}
示例#9
0
static void terminate_write(struct davinci_i2c_dev *dev)
{
	rt_uint16_t 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)
		i2c_dbg("TDR IRQ while no data to send\n");
}
示例#10
0
文件: i2c_dev.c 项目: dlts200466/dew
static rt_size_t i2c_bus_device_read (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t count)
{
	struct rt_i2c_bus* bus;
	struct rt_i2c_device *i2c_device = dev->user_data;
	
	bus = i2c_device->bus;
	RT_ASSERT(bus != RT_NULL);
	RT_ASSERT(i2c_device != RT_NULL);
	RT_ASSERT(buffer != RT_NULL);

	i2c_dbg("I2C bus dev [%s] reading %u bytes.\n", bus->name, count);

	return rt_i2c_master_recv(i2c_device, buffer, count);
}
示例#11
0
文件: i2c_dev.c 项目: dlts200466/dew
static rt_size_t i2c_bus_device_write (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
	struct rt_i2c_bus* bus;
	struct rt_i2c_device *i2c_device = dev->user_data;
	
	bus = i2c_device->bus;
	RT_ASSERT(bus != RT_NULL);
	RT_ASSERT(i2c_device != RT_NULL);
	RT_ASSERT(buffer != RT_NULL);

	i2c_dbg("I2C bus dev writing %u bytes.\n", bus->name, size);

	return rt_i2c_master_send(i2c_device, buffer, size);
}
示例#12
0
static inline int i2c_recv_byte(struct saa7134_dev *dev)
{
	enum i2c_status status;
	unsigned char data;

	i2c_set_attr(dev,CONTINUE);
	if (!i2c_is_busy_wait(dev))
		return -EIO;
	status = i2c_get_status(dev);
	if (i2c_is_error(status))
		return -EIO;
	data = saa_readb(SAA7134_I2C_DATA);
	i2c_dbg(2, "i2c data <= 0x%x\n", data);
	return data;
}
示例#13
0
rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
                                    const char               *bus_name)
{
    rt_err_t res = RT_EOK;

    rt_mutex_init(&bus->lock, "i2c_bus_lock", RT_IPC_FLAG_FIFO);

    if (bus->timeout == 0) bus->timeout = RT_TICK_PER_SECOND;

    res = rt_i2c_bus_device_device_init(bus, bus_name);

    i2c_dbg("I2C bus [%s] registered\n", bus_name);

    return res;
}
示例#14
0
struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name)
{
    struct rt_i2c_bus_device *bus;
    rt_device_t dev = rt_device_find(bus_name);
    if (dev == RT_NULL || dev->type != RT_Device_Class_I2CBUS)
    {
        i2c_dbg("I2C bus %s not exist\n", bus_name);

        return RT_NULL;
    }

    bus = (struct rt_i2c_bus_device *)dev->user_data;

    return bus;
}
/* 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;
}
示例#16
0
/* This routine does i2c bus recovery as specified in the
 * i2c protocol Rev. 03 section 3.16 titled "Bus clear"
 */
static void i2c_recover_bus(struct davinci_i2c_dev *dev)
{
	rt_uint32_t flag = 0;

	i2c_dbg("initiating i2c bus recovery\n");
	/* Send NACK to the slave */
	flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
	flag |=  DAVINCI_I2C_MDR_NACK;
	/* write the data into mode register */
	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
#if 0
	if (pdata)
		generic_i2c_clock_pulse(pdata->scl_pin);
#endif
	/* Send STOP */
	flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
	flag |= DAVINCI_I2C_MDR_STP;
	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
}
示例#17
0
static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
{
	rt_uint16_t psc;
	rt_uint32_t clk;
	rt_uint32_t d;
	rt_uint32_t clkh;
	rt_uint32_t clkl;
	rt_uint32_t input_clock = clk_get_rate(dev->clk);

	/* 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
	 */

	/* get minimum of 7 MHz clock, but max of 12 MHz */
	psc = (input_clock / 7000000) - 1;
	if ((input_clock / (psc + 1)) > 12000000)
		psc++;	/* better to run under spec than over */
	d = (psc >= 2) ? 5 : 7 - psc;

	clk = ((input_clock / (psc + 1)) / (dev->bus_freq * 1000)) - (d << 1);
	clkh = clk >> 1;
	clkl = clk - clkh;

	davinci_i2c_write_reg(dev, DAVINCI_I2C_PSC_REG, psc);
	davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);
	davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl);

	i2c_dbg("input_clock = %d, CLK = %d\n", input_clock, clk);
}
示例#18
0
static int rk29_event_occurred(struct rk29_i2c_data *i2c)
{
	unsigned long isr, lsr;

	isr = readl(i2c->regs + I2C_ISR);
	lsr = readl(i2c->regs + I2C_LSR);
	i2c_dbg(i2c->dev,"event occurred, isr = %lx, lsr = %lx\n", isr, lsr);
	if(isr & I2C_ISR_ARBITR_LOSE)
	{
		writel(0, i2c->regs + I2C_ISR);
		i2c->cmd_err = RK29_ERROR_ARBITR_LOSE;
		i2c_err(i2c->dev, "<error>arbitration loss\n");
		return 0;
	}

	switch(i2c->cmd_event)
	{
		case RK29_EVENT_MTX_RCVD_ACK:
			if(isr & I2C_ISR_MTX_RCVD_ACK)
			{
				isr &= ~I2C_ISR_MTX_RCVD_ACK;
				writel(isr, i2c->regs + I2C_ISR);
				return 1;
			}
		break;
		case RK29_EVENT_MRX_NEED_ACK:
			if(isr & I2C_ISR_MRX_NEED_ACK)
			{
				isr &= ~I2C_ISR_MRX_NEED_ACK;
				writel(isr, i2c->regs + I2C_ISR);
				return 1;
			}
			break;
		default:
			break;
	}
	writel(0, i2c->regs + I2C_ISR);
	i2c->cmd_err = RK29_ERROR_UNKNOWN;
	return 0;
}
示例#19
0
static int rk29_send_2nd_addr(struct rk29_i2c_data *i2c,
						struct i2c_msg *msg, int start)
{
	int ret = 0;
	unsigned long lsr;
	unsigned long addr_2nd = msg->addr & 0xff;

	i2c_dbg(i2c->dev, "i2c send addr_2nd: %lx\n", addr_2nd);	
	writel(addr_2nd, i2c->regs + I2C_MTXR);
	if(i2c->mode == I2C_MODE_IRQ)
		INIT_COMPLETION(i2c->cmd_complete);
	writel(I2C_LCMR_RESUME, i2c->regs + I2C_LCMR);
	rk29_set_ack(i2c);
	
	if((ret = rk29_wait_event(i2c, RK29_EVENT_MTX_RCVD_ACK)) != 0)
	{
		i2c_err(i2c->dev, "after sent addr_2nd, i2c wait for ACK timeout\n");
		return ret;
	}
	lsr = readl(i2c->regs + I2C_LSR);
	if((lsr & I2C_LSR_RCV_NAK) && !(msg->flags & I2C_M_IGNORE_NAK))
		return -EINVAL;
	return ret;
}
示例#20
0
/** \brief set system time(date not modify).
 *
 * \param rt_uint32_t hour   e.g: 0~23.
 * \param rt_uint32_t minute e.g: 0~59.
 * \param rt_uint32_t second e.g: 0~59.
 * \return rt_err_t if set success, return RT_EOK.
 *
 */
rt_err_t i2c(rt_uint8_t wr, rt_uint32_t addr, rt_uint32_t reg, rt_uint32_t data)
{
    struct rt_i2c_priv_data i2c_priv_data;
    struct rt_i2c_msg i2c_msg[2];
    rt_uint8_t i2c_data[10];
    rt_device_t device;
    rt_err_t ret = -RT_ERROR;

    device = rt_device_find("I2C");
    if (device == RT_NULL)
    {
        i2c_err("Can't find I2C device.\n");
        return -RT_ERROR;
    }

    if(!wr)
    {
        // Write Action
        i2c_msg[0].addr=addr;
        i2c_msg[0].flags=RT_I2C_WR ;
        i2c_msg[0].len=2;
        i2c_data[0]=reg;
        i2c_data[1]=data;
        i2c_msg[0].buf=i2c_data;

        i2c_priv_data.msgs=i2c_msg;
        i2c_priv_data.number=1;

        if (rt_device_open(device, 0) == RT_EOK)
        {
            i2c_dbg("write msg addr=0x%x, len=%d, reg=0x%d,  data=0x%x\n",i2c_msg[0].addr, i2c_msg[0].len, i2c_data[0], i2c_data[1]);
            rt_device_control(device, RT_I2C_DEV_CTRL_RW, &i2c_priv_data);
            rt_device_close(device);
        }
        else
        {
            i2c_err("open:w err\n");
            goto l_err;
        }
    }
    else
    {
        // Read Action
        // Write reg addr msg
        i2c_msg[0].addr=addr;
        i2c_msg[0].flags=RT_I2C_WR;
        i2c_msg[0].len=1;
        i2c_data[0]=reg;
        i2c_msg[0].buf=i2c_data;
        // Read data msg
        i2c_msg[1].addr=addr;
        i2c_msg[1].flags=RT_I2C_RD;
        i2c_msg[1].len=1;
        i2c_data[1]=0;
        i2c_msg[1].buf=&i2c_data[1];

        i2c_priv_data.msgs=i2c_msg;
        i2c_priv_data.number=2;

        if (rt_device_open(device, 0) == RT_EOK)
        {
            rt_device_control(device, RT_I2C_DEV_CTRL_RW, &i2c_priv_data);
            i2c_dbg("read msg addr=0x%x, len=%d, addr=0x%d,  data=0x%x\n",i2c_msg[0].addr, i2c_msg[0].len, i2c_data[0], i2c_data[1]);
            rt_device_close(device);
        }
        else
        {

            i2c_err("open:r err\n");
            goto l_err;
        }
    }

l_err:
    return ret;
}
示例#21
0
static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
			    struct i2c_msg *msgs, int num)
{
	struct saa7134_dev *dev = i2c_adap->algo_data;
	enum i2c_status status;
	unsigned char data;
	int addr,rc,i,byte;

	status = i2c_get_status(dev);
	if (!i2c_is_idle(status))
		if (!i2c_reset(dev))
			return -EIO;

	i2c_dbg(2, "start xfer\n");
	i2c_dbg(1, "i2c xfer:");
	for (i = 0; i < num; i++) {
		if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) {
			/* send address */
			i2c_dbg(2, "send address\n");
			addr  = msgs[i].addr << 1;
			if (msgs[i].flags & I2C_M_RD)
				addr |= 1;
			if (i > 0 && msgs[i].flags &
			    I2C_M_RD && msgs[i].addr != 0x40 &&
			    msgs[i].addr != 0x41 &&
			    msgs[i].addr != 0x19) {
				/* workaround for a saa7134 i2c bug
				 * needed to talk to the mt352 demux
				 * thanks to pinnacle for the hint */
				int quirk = 0xfe;
				i2c_cont(1, " [%02x quirk]", quirk);
				i2c_send_byte(dev,START,quirk);
				i2c_recv_byte(dev);
			}
			i2c_cont(1, " < %02x", addr);
			rc = i2c_send_byte(dev,START,addr);
			if (rc < 0)
				 goto err;
		}
		if (msgs[i].flags & I2C_M_RD) {
			/* read bytes */
			i2c_dbg(2, "read bytes\n");
			for (byte = 0; byte < msgs[i].len; byte++) {
				i2c_cont(1, " =");
				rc = i2c_recv_byte(dev);
				if (rc < 0)
					goto err;
				i2c_cont(1, "%02x", rc);
				msgs[i].buf[byte] = rc;
			}
			/* discard mysterious extra byte when reading
			   from Samsung S5H1411.  i2c bus gets error
			   if we do not. */
			if (0x19 == msgs[i].addr) {
				i2c_cont(1, " ?");
				rc = i2c_recv_byte(dev);
				if (rc < 0)
					goto err;
				i2c_cont(1, "%02x", rc);
			}
		} else {
			/* write bytes */
			i2c_dbg(2, "write bytes\n");
			for (byte = 0; byte < msgs[i].len; byte++) {
				data = msgs[i].buf[byte];
				i2c_cont(1, " %02x", data);
				rc = i2c_send_byte(dev,CONTINUE,data);
				if (rc < 0)
					goto err;
			}
		}
	}
	i2c_dbg(2, "xfer done\n");
	i2c_cont(1, " >");
	i2c_set_attr(dev,STOP);
	rc = -EIO;
	if (!i2c_is_busy_wait(dev))
		goto err;
	status = i2c_get_status(dev);
	if (i2c_is_error(status))
		goto err;
	/* ensure that the bus is idle for at least one bit slot */
	msleep(1);

	i2c_cont(1, "\n");
	return num;
 err:
	if (1 == i2c_debug) {
		status = i2c_get_status(dev);
		i2c_cont(1, " ERROR: %s\n", str_i2c_status[status]);
	}
	return rc;
}
示例#22
0
static inline void i2c_set_attr(struct saa7134_dev *dev, enum i2c_attr attr)
{
	i2c_dbg(2, "i2c attr => %s\n", str_i2c_attr[attr]);
	saa_andorb(SAA7134_I2C_ATTR_STATUS,0xc0,attr << 6);
}
/* 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;
}
示例#24
0
rt_size_t i2c1_master_xfer(struct rt_i2c_bus_device *bus,
						 struct rt_i2c_msg msgs[],
						 rt_uint32_t num)
{int de=0;
	struct rt_i2c_msg *msg;
    rt_int32_t i, ret;
	rt_tick_t tick=rt_tick_get();
	
	GPIO_SetBits(GPIOB,GPIO_Pin_8|GPIO_Pin_9);
	while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
		CHECKTIME(tick);
 	I2C_GenerateSTART(I2Cx, ENABLE);
    /* Test on EV5 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
		CHECKTIME(tick);

    for (i = 0; i < num; i++)
    {de=0;
        msg = &msgs[i];
        if (!(msg->flags & RT_I2C_NO_START))
        {
            if (i)
            {
                I2C_GenerateSTART(I2Cx, ENABLE);
				while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
					CHECKTIME(tick);
            }de=1;
            if (msg->flags & RT_I2C_RD)
			{
				I2C_Send7bitAddress(I2Cx, msg->addr, I2C_Direction_Receiver);
                while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
					CHECKTIME(tick);
			}
            else
			{
				I2C_Send7bitAddress(I2Cx, msg->addr, I2C_Direction_Transmitter);
                while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
					CHECKTIME(tick);
			}
			I2C_Cmd(I2Cx, ENABLE);
        }
        if (msg->flags & RT_I2C_RD)
        {
            ret = i2c1_recv_bytes(msg);
            if (ret >= 1)
                i2c_dbg("read %d byte%s\n",
                        ret, ret == 1 ? "" : "s");
			
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_EIO;
                goto out;
            }
        }
        else
        {
			nostart=(i+1<num && (msg[i+1].flags & RT_I2C_NO_START))
							||(msg[i].flags & I2C_RA);
            ret = stm32_i2c_send_bytes(msg);
            if (ret >= 1)
                i2c_dbg("write %d byte%s\n",
                        ret, ret == 1 ? "" : "s");
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_ERROR;
                goto out;
            }
        }
    }
    ret = i;
	
    return ret;
out:
	de=-1;
	if(de==0)GPIO_ResetBits(GPIOB,GPIO_Pin_8);else if(de==1)GPIO_ResetBits(GPIOB,GPIO_Pin_9);
    i2c_dbg("error on stage %d\n",de);
//    I2C_GenerateSTOP(I2Cx, ENABLE);
	
    return ret;
}
示例#25
0
static inline void i2c_set_status(struct saa7134_dev *dev,
				  enum i2c_status status)
{
	i2c_dbg(2, "i2c stat => %s\n", str_i2c_status[status]);
	saa_andorb(SAA7134_I2C_ATTR_STATUS,0x0f,status);
}
示例#26
0
static rt_size_t stm32_i2c_xfer(struct rt_i2c_bus_device *bus,
                                struct rt_i2c_msg msgs[], rt_uint32_t num)
{
    struct rt_i2c_msg *msg;
    rt_int32_t i, ret;

    I2C_GenerateSTART(I2C1, ENABLE);
    /* Test on EV5 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

    for (i = 0; i < num; i++)
    {
        msg = &msgs[i];
        if (!(msg->flags & RT_I2C_NO_START))
        {
            if (i)
            {
                I2C_GenerateSTART(I2C1, ENABLE);
            }
            I2C_SendAddress(I2C1, msg);
            if (msg->flags & RT_I2C_RD)
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
            else
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

        }
        if (msg->flags & RT_I2C_RD)
        {
            if (!(msg->flags & RT_I2C_NO_READ_ACK))
                I2C_AcknowledgeConfig(I2C1,ENABLE);
            else
                I2C_AcknowledgeConfig(I2C1,DISABLE);
            ret = stm32_i2c_recv_bytes(I2C1, msg);
            if (ret >= 1)
                i2c_dbg("read %d byte%s\n",
                        ret, ret == 1 ? "" : "s");
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_EIO;
                goto out;
            }
        }
        else
        {
            ret = stm32_i2c_send_bytes(I2C1, msg);
            if (ret >= 1)
                i2c_dbg("write %d byte%s\n",
                        ret, ret == 1 ? "" : "s");
            if (ret < msg->len)
            {
                if (ret >= 0)
                    ret = -RT_ERROR;
                goto out;
            }
        }
    }
    ret = i;

out:
    i2c_dbg("send stop condition\n");
    I2C_GenerateSTOP(I2C1, ENABLE);

    return ret;
}
示例#27
0
/*
 * Interrupt service routine. This gets called whenever an I2C interrupt
 * occurs.
 */
static void i2c_davinci_isr(int irq, void *param)
{
	struct davinci_i2c_dev *dev = (struct davinci_i2c_dev *)param;
	rt_uint32_t stat;
	int count = 0;
	rt_uint16_t w;

	while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
		i2c_dbg("%s: stat=0x%x\n", __func__, stat);
		if (count++ == 100) {
			rt_kprintf("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;
			rt_sem_release(&dev->completion);
			break;

		case DAVINCI_I2C_IVR_NACK:
			dev->cmd_err |= DAVINCI_I2C_STR_NACK;
			dev->buf_len = 0;
			rt_sem_release(&dev->completion);
			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);
			}
			rt_sem_release(&dev->completion);
			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);
			rt_sem_release(&dev->completion);
			break;

		case DAVINCI_I2C_IVR_AAS:
			i2c_dbg("Address as slave interrupt\n");
			break;

		default:
			i2c_dbg("Unrecognized irq stat %d\n", stat);
			break;
		}
	}

}