Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 924a93ed authored by Daniel Kurtz's avatar Daniel Kurtz Committed by Daniel Vetter
Browse files

drm/i915/intel_i2c: refactor gmbus_xfer



Split out gmbus_xfer_read/write() helper functions.

Signed-off-by: default avatarDaniel Kurtz <djkurtz@chromium.org>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent e7e58eb5
Loading
Loading
Loading
Loading
+92 −59
Original line number Original line Diff line number Diff line
@@ -198,46 +198,29 @@ intel_i2c_quirk_xfer(struct intel_gmbus *bus,
}
}


static int
static int
gmbus_xfer(struct i2c_adapter *adapter,
gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
	   struct i2c_msg *msgs,
		bool last)
	   int num)
{
{
	struct intel_gmbus *bus = container_of(adapter,
	int reg_offset = dev_priv->gpio_mmio_base;
					       struct intel_gmbus,
	u16 len = msg->len;
					       adapter);
	u8 *buf = msg->buf;
	struct drm_i915_private *dev_priv = bus->dev_priv;
	int i, reg_offset, ret;

	mutex_lock(&dev_priv->gmbus_mutex);

	if (bus->force_bit) {
		ret = intel_i2c_quirk_xfer(bus, msgs, num);
		goto out;
	}

	reg_offset = dev_priv->gpio_mmio_base;

	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);

	for (i = 0; i < num; i++) {
		u16 len = msgs[i].len;
		u8 *buf = msgs[i].buf;


		if (msgs[i].flags & I2C_M_RD) {
	I915_WRITE(GMBUS1 + reg_offset,
	I915_WRITE(GMBUS1 + reg_offset,
		   GMBUS_CYCLE_WAIT |
		   GMBUS_CYCLE_WAIT |
				   (i + 1 == num ? GMBUS_CYCLE_STOP : 0) |
		   (last ? GMBUS_CYCLE_STOP : 0) |
		   (len << GMBUS_BYTE_COUNT_SHIFT) |
		   (len << GMBUS_BYTE_COUNT_SHIFT) |
				   (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
		   (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) |
		   GMBUS_SLAVE_READ | GMBUS_SW_RDY);
		   GMBUS_SLAVE_READ | GMBUS_SW_RDY);
	POSTING_READ(GMBUS2 + reg_offset);
	POSTING_READ(GMBUS2 + reg_offset);
	do {
	do {
		u32 val, loop = 0;
		u32 val, loop = 0;


				if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50))
		if (wait_for(I915_READ(GMBUS2 + reg_offset) &
					goto timeout;
			     (GMBUS_SATOER | GMBUS_HW_RDY),
			     50))
			return -ETIMEDOUT;
		if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
		if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
					goto clear_err;
			return -ENXIO;


		val = I915_READ(GMBUS3 + reg_offset);
		val = I915_READ(GMBUS3 + reg_offset);
		do {
		do {
@@ -245,7 +228,17 @@ gmbus_xfer(struct i2c_adapter *adapter,
			val >>= 8;
			val >>= 8;
		} while (--len && ++loop < 4);
		} while (--len && ++loop < 4);
	} while (len);
	} while (len);
		} else {

	return 0;
}

static int
gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
		bool last)
{
	int reg_offset = dev_priv->gpio_mmio_base;
	u16 len = msg->len;
	u8 *buf = msg->buf;
	u32 val, loop;
	u32 val, loop;


	val = loop = 0;
	val = loop = 0;
@@ -256,17 +249,18 @@ gmbus_xfer(struct i2c_adapter *adapter,
	I915_WRITE(GMBUS3 + reg_offset, val);
	I915_WRITE(GMBUS3 + reg_offset, val);
	I915_WRITE(GMBUS1 + reg_offset,
	I915_WRITE(GMBUS1 + reg_offset,
		   GMBUS_CYCLE_WAIT |
		   GMBUS_CYCLE_WAIT |
				   (i + 1 == num ? GMBUS_CYCLE_STOP : 0) |
		   (last ? GMBUS_CYCLE_STOP : 0) |
				   (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) |
		   (msg->len << GMBUS_BYTE_COUNT_SHIFT) |
				   (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
		   (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) |
		   GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
		   GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
	POSTING_READ(GMBUS2 + reg_offset);
	POSTING_READ(GMBUS2 + reg_offset);

	while (len) {
	while (len) {
				if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50))
		if (wait_for(I915_READ(GMBUS2 + reg_offset) &
					goto timeout;
			     (GMBUS_SATOER | GMBUS_HW_RDY),
			     50))
			return -ETIMEDOUT;
		if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
		if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
					goto clear_err;
			return -ENXIO;


		val = loop = 0;
		val = loop = 0;
		do {
		do {
@@ -276,9 +270,48 @@ gmbus_xfer(struct i2c_adapter *adapter,
		I915_WRITE(GMBUS3 + reg_offset, val);
		I915_WRITE(GMBUS3 + reg_offset, val);
		POSTING_READ(GMBUS2 + reg_offset);
		POSTING_READ(GMBUS2 + reg_offset);
	}
	}
	return 0;
}
}


		if (i + 1 < num && wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50))
static int
gmbus_xfer(struct i2c_adapter *adapter,
	   struct i2c_msg *msgs,
	   int num)
{
	struct intel_gmbus *bus = container_of(adapter,
					       struct intel_gmbus,
					       adapter);
	struct drm_i915_private *dev_priv = bus->dev_priv;
	int i, reg_offset, ret;

	mutex_lock(&dev_priv->gmbus_mutex);

	if (bus->force_bit) {
		ret = intel_i2c_quirk_xfer(bus, msgs, num);
		goto out;
	}

	reg_offset = dev_priv->gpio_mmio_base;

	I915_WRITE(GMBUS0 + reg_offset, bus->reg0);

	for (i = 0; i < num; i++) {
		bool last = i + 1 == num;

		if (msgs[i].flags & I2C_M_RD)
			ret = gmbus_xfer_read(dev_priv, &msgs[i], last);
		else
			ret = gmbus_xfer_write(dev_priv, &msgs[i], last);

		if (ret == -ETIMEDOUT)
			goto timeout;
		if (ret == -ENXIO)
			goto clear_err;

		if (!last &&
		    wait_for(I915_READ(GMBUS2 + reg_offset) &
			     (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE),
			     50))
			goto timeout;
			goto timeout;
		if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
		if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER)
			goto clear_err;
			goto clear_err;