static int
qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
	DECLARE_COMPLETION_ONSTACK(complete);
	struct qup_i2c_dev *dev = i2c_get_adapdata(adap);
	int ret;
	int rem = num;
	long timeout;
	int err;
	unsigned long flags;

	del_timer_sync(&dev->pwr_timer);
	mutex_lock(&dev->mlock);

	if (dev->suspended) {
		mutex_unlock(&dev->mlock);
		dev_err(dev->dev, "qup_i2c_xfer: dev suspended, return Error!\n");
		return -EIO;
	}

	if (dev->clk_state == 0) {
		if (dev->clk_ctl == 0) {
			if (dev->pdata->src_clk_rate > 0)
				clk_set_rate(dev->clk,
						dev->pdata->src_clk_rate);
			else
				dev->pdata->src_clk_rate = 19200000;
		}
		qup_i2c_pwr_mgmt(dev, 1);
	}
	/* Initialize QUP registers during first transfer */
	if (dev->clk_ctl == 0) {
		int fs_div;
		int hs_div;
		uint32_t fifo_reg;

		if (dev->gsbi) {
			writel(0x2 << 4, dev->gsbi);
			/* GSBI memory is not in the same 1K region as other
			 * QUP registers. dsb() here ensures that the GSBI
			 * register is updated in correct order and that the
			 * write has gone through before programming QUP core
			 * registers
			 */
			dsb();
		}

		fs_div = ((dev->pdata->src_clk_rate
				/ dev->pdata->clk_freq) / 2) - 3;
		hs_div = 3;
		dev->clk_ctl = ((hs_div & 0x7) << 8) | (fs_div & 0xff);
		fifo_reg = readl(dev->base + QUP_IO_MODE);
		if (fifo_reg & 0x3)
			dev->out_blk_sz = (fifo_reg & 0x3) * 16;
		else
			dev->out_blk_sz = 16;
		if (fifo_reg & 0x60)
			dev->in_blk_sz = ((fifo_reg & 0x60) >> 5) * 16;
		else
Exemple #2
0
static void
qup_i2c_pwr_timer(unsigned long data)
{
	struct qup_i2c_dev *dev = (struct qup_i2c_dev *) data;
	dev_dbg(dev->dev, "QUP_Power: Inactivity based power management\n");
	if (dev->clk_state == 1)
		qup_i2c_pwr_mgmt(dev, 0);
}
Exemple #3
0
static int
qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
	DECLARE_COMPLETION_ONSTACK(complete);
	struct qup_i2c_dev *dev = i2c_get_adapdata(adap);
	int ret;
	int rem = num;
	long timeout;
	int err;
#ifdef QUP_I2C_SPINLOCK_ENABLE
    unsigned long flags;  //p11171 dongseok added
#endif

	del_timer_sync(&dev->pwr_timer);
	mutex_lock(&dev->mlock);

	if (dev->suspended) {
		mutex_unlock(&dev->mlock);
		return -EIO;
	}

	if (dev->clk_state == 0) {
		if (dev->clk_ctl == 0) {
			if (dev->pdata->src_clk_rate > 0)
				clk_set_rate(dev->clk,
						dev->pdata->src_clk_rate);
			else
				dev->pdata->src_clk_rate = 19200000;
		}
		qup_i2c_pwr_mgmt(dev, 1);
	}
	/* Initialize QUP registers during first transfer */
	if (dev->clk_ctl == 0) {
		int fs_div;
		int hs_div;
		uint32_t fifo_reg;

		if (dev->gsbi)
			writel(0x2 << 4, dev->gsbi);

		fs_div = ((dev->pdata->src_clk_rate
				/ dev->pdata->clk_freq) / 2) - 3;
		hs_div = 3;
		dev->clk_ctl = ((hs_div & 0x7) << 8) | (fs_div & 0xff);
		fifo_reg = readl(dev->base + QUP_IO_MODE);
		if (fifo_reg & 0x3)
			dev->out_blk_sz = (fifo_reg & 0x3) * 16;
		else
			dev->out_blk_sz = 16;
		if (fifo_reg & 0x60)
			dev->in_blk_sz = ((fifo_reg & 0x60) >> 5) * 16;
		else
Exemple #4
0
static int
qup_i2c_sub_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num, int cnt)
#endif /* #if defined( CONFIG_I2C_CUST_SH ) */
{
	DECLARE_COMPLETION_ONSTACK(complete);
	struct qup_i2c_dev *dev = i2c_get_adapdata(adap);
	int ret;
	int rem = num;
	long timeout;
	int err;
#if defined( CONFIG_I2C_CUST_SH )
	char slave_adr;
#endif /* #if defined( CONFIG_I2C_CUST_SH ) */

#if defined( CONFIG_I2C_CUST_SH )
#else
	del_timer_sync(&dev->pwr_timer);
#endif /* #if defined( CONFIG_I2C_CUST_SH ) */

	mutex_lock(&dev->mlock);

	if (dev->suspended) {
#if defined( CONFIG_I2C_CUST_SH )
		uint32_t loop_cnt;

		for(loop_cnt=0;loop_cnt<SH_I2C_SUSPEND_RETRY;loop_cnt++){
			if(dev->suspended == 0)
				break;
			msleep(20);
		}
		if(dev->suspended == 1){
			mutex_unlock(&dev->mlock);
			dev_err(dev->dev,
				"Error: waiting for resume...[Addr=0x%x]\n",
											(char)msgs->addr << 1);
			return -EIO;
		}
#else
		mutex_unlock(&dev->mlock);
		return -EIO;
#endif /* #if defined( CONFIG_I2C_CUST_SH ) */
	}

	if (dev->clk_state == 0) {
		if (dev->clk_ctl == 0) {
			if (dev->pdata->src_clk_rate > 0)
				clk_set_rate(dev->clk,
						dev->pdata->src_clk_rate);
			else
				dev->pdata->src_clk_rate = 19200000;
		}
		qup_i2c_pwr_mgmt(dev, 1);
	}
	/* Initialize QUP registers during first transfer */
	if (dev->clk_ctl == 0) {
		int fs_div;
		int hs_div;
		uint32_t fifo_reg;

		if (dev->gsbi)
			writel(0x2 << 4, dev->gsbi);

		fs_div = ((dev->pdata->src_clk_rate
				/ dev->pdata->clk_freq) / 2) - 3;
		hs_div = 3;
		dev->clk_ctl = ((hs_div & 0x7) << 8) | (fs_div & 0xff);
		fifo_reg = readl(dev->base + QUP_IO_MODE);
		if (fifo_reg & 0x3)
			dev->out_blk_sz = (fifo_reg & 0x3) * 16;
		else
			dev->out_blk_sz = 16;
		if (fifo_reg & 0x60)
			dev->in_blk_sz = ((fifo_reg & 0x60) >> 5) * 16;
		else