static int bcmpmu_i2c_try_write(struct bcmpmu59xxx *bcmpmu, u32 reg, u8 value)
{
	int err = 0;
	int tries = PWRMGR_I2C_RDWR_MAX_TRIES;
	u8 temp = 0;
	u8 check_fifo = DEC_REG_FLAG(reg) & 1;
	if (DEC_REG_ADD(reg) >= PMU_REG_MAX)
		return -ENODEV;
	while (tries--) {
		if (check_fifo && (last_trans == I2C_TRANS_WRITE)) {
			err =
			pwr_mgr_pmu_reg_read((u8)
						DEC_REG_ADD(PMU_REG_I2CCTRL1),
						bcmpmu_get_slaveid(bcmpmu,
						PMU_REG_I2CCTRL1),
						&temp);
			if (err == 0) {
				if (!(temp & I2CCTRL1_FIFOFULL_MASK)) {
					err = pwr_mgr_pmu_reg_write
					    ((u8) DEC_REG_ADD(reg),
					     bcmpmu_get_slaveid(bcmpmu, reg),
					     value);
					if (err == 0) {
						last_trans = I2C_TRANS_WRITE;
						break;
					}
				}
			}
			udelay(PWRMGR_I2C_RETRY_DELAY_US);
		} else {
			err =
			    pwr_mgr_pmu_reg_write((u8) DEC_REG_ADD(reg),
						  bcmpmu_get_slaveid(bcmpmu,
								     reg),
						  value);
			if (err == 0) {
				last_trans = I2C_TRANS_WRITE;
				break;
			}
		}
	}
	if (tries <= 0) {
		err = -EAGAIN;
		pr_pmui2c(ERROR, "ERR: I2C SW SEQ Write MAX Tries\n");
	}
	if (!err)
		bcmpmu_i2c_log(i2c_log_buf_v, 0,
				bcmpmu_get_slaveid(bcmpmu, reg),
				DEC_REG_ADD(reg),
				value);
	else
		bcmpmu_i2c_log(i2c_log_buf_v, (char)err,
				bcmpmu_get_slaveid(bcmpmu, reg),
				DEC_REG_ADD(reg),
				value);

	return err;
}
/**
 * function must be called with i2c_mutex locked
 */
static int i2c_try_read_write(struct bcmpmu *bcmpmu, int trans_type,
			      u8 reg_addr, u8 slave_id, u8 *value)
{
	struct bcmpmu_reg_map map;
	struct bcmpmu_i2c *acc = (struct bcmpmu_i2c *)bcmpmu->accinfo;
	int err = 0;
	int tries = PWRMGR_I2C_RDWR_MAX_TRIES;
	u8 clientaddr;
	u8 temp;

	pr_debug("%s: trans %d addr %x, slave %x\n", __func__,
			trans_type, reg_addr, slave_id);

	if (trans_type == I2C_TRANS_READ)
		map = bcmpmu->regmap[PMU_REG_BUS_STATUS_READ_FIFO];
	else
		map = bcmpmu->regmap[PMU_REG_BUS_STATUS_WRITE_FIFO];

	if ((map.addr == 0) && (map.mask == 0)) {
		err = -ENXIO;
		goto err_out;
	}
	if (map.map == 0)
		clientaddr = acc->i2c_client->addr;
	else
		clientaddr = acc->i2c_client1->addr;

	switch (trans_type) {
	case I2C_TRANS_READ:
		while (tries--) {
			/**
			 * Read the FIFORDBLOCK Bit of PMU before
			 * initiating an read transaction if the last
			 * trasaction was i2c write. This bit is set by
			 * the
			 * PMU when its busy finishing previous write
			 * operation (if this bit is ignored there is a
			 * chance of reading a stale data of the
			 * register !!)
			 */

			if (last_i2c_trans == I2C_TRANS_WRITE) {
				err = pwr_mgr_pmu_reg_read(map.addr,
						clientaddr,
						&temp);
				if (err == 0) {
					if ((temp & map.mask) ==
						bcmpmu->pmu_rev) {
						/**
						 * OK: Now we can try
						 * to read the register
						 */
						err =
						pwr_mgr_pmu_reg_read(reg_addr,
								slave_id,
								value);
						if (err == 0) {
							last_i2c_trans =
								I2C_TRANS_READ;
							break;
						}
					}
				}
			} else {
				err = pwr_mgr_pmu_reg_read(reg_addr,
						slave_id,
						value);
				if (err == 0) {
					last_i2c_trans = I2C_TRANS_READ;
					break;
				}
			}
			udelay(PWRMGR_I2C_RETRY_DELAY_US);
		}
		if (tries <= 0) {
			pr_info("ERROR: I2C SW SEQ Max Tries\n");
			err = -EAGAIN;
			break;
		}
		break;
	case I2C_TRANS_WRITE:
		while (tries--) {
			if (last_i2c_trans == I2C_TRANS_WRITE) {
				err = pwr_mgr_pmu_reg_read(map.addr,
						clientaddr, &temp);
				if (err == 0) {
					if (!(temp & map.mask)) {
						err = pwr_mgr_pmu_reg_write(
								reg_addr,
								slave_id,
								*value);
						if (err == 0) {
							last_i2c_trans =
								I2C_TRANS_WRITE;
							break;
						}
					}
				}
				udelay(PWRMGR_I2C_RETRY_DELAY_US);
			} else {
				err = pwr_mgr_pmu_reg_write(reg_addr, slave_id,
						*value);
				if (err == 0) {
					last_i2c_trans =
						I2C_TRANS_WRITE;
					break;
				}
			}
		}
		if (tries <= 0) {
			err = -EAGAIN;
			pr_info("ERROR: I2C SW SEQ Write MAX Tries\n");
			break;
		}
		break;
	default:
		err = -EINVAL;
		break;
	}
err_out:
	return err;
}