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

Commit f899fc64 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: use GMBUS to manage i2c links



Use the GMBUS interface rather than direct bit banging to grab the EDID
over DDC (and for other forms of auxiliary communication with external
display controllers). The hope is that this method will be much faster
and more reliable than bit banging for fetching EDIDs from buggy monitors
or through switches, though we still preserve the bit banging as a
fallback in case GMBUS fails.

Based on an original patch by Jesse Barnes.

Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 373a3cf7
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include "drmP.h"
#include "drm_edid.h"
#include "drm_edid_modes.h"
+3 −6
Original line number Diff line number Diff line
@@ -168,7 +168,6 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode);
static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val)
{
	struct i2c_adapter *adapter = dvo->i2c_bus;
	struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
	u8 out_buf[2];
	u8 in_buf[2];

@@ -190,7 +189,7 @@ static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val)
	out_buf[0] = addr;
	out_buf[1] = 0;

	if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) {
	if (i2c_transfer(adapter, msgs, 2) == 2) {
		*val= in_buf[0];
		return true;
	};
@@ -201,7 +200,6 @@ static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val)
static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val)
{
	struct i2c_adapter *adapter = dvo->i2c_bus;
	struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
	uint8_t out_buf[2];
	struct i2c_msg msg = {
		.addr = dvo->slave_addr,
@@ -213,7 +211,7 @@ static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val)
	out_buf[0] = addr;
	out_buf[1] = val;

	if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1)
	if (i2c_transfer(adapter, &msg, 1) == 1)
		return true;

	return false;
@@ -223,7 +221,6 @@ static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val)
static bool ch7017_init(struct intel_dvo_device *dvo,
			struct i2c_adapter *adapter)
{
	struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
	struct ch7017_priv *priv;
	uint8_t val;

@@ -242,7 +239,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo,
	    val != CH7019_DEVICE_ID_VALUE) {
		DRM_DEBUG_KMS("ch701x not detected, got %d: from %s "
				"Slave %d.\n",
			  val, i2cbus->adapter.name,dvo->slave_addr);
			  val, adapter->name,dvo->slave_addr);
		goto fail;
	}

+4 −6
Original line number Diff line number Diff line
@@ -113,7 +113,6 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
{
	struct ch7xxx_priv *ch7xxx= dvo->dev_priv;
	struct i2c_adapter *adapter = dvo->i2c_bus;
	struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
	u8 out_buf[2];
	u8 in_buf[2];

@@ -135,14 +134,14 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
	out_buf[0] = addr;
	out_buf[1] = 0;

	if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) {
	if (i2c_transfer(adapter, msgs, 2) == 2) {
		*ch = in_buf[0];
		return true;
	};

	if (!ch7xxx->quiet) {
		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
			  addr, i2cbus->adapter.name, dvo->slave_addr);
			  addr, adapter->name, dvo->slave_addr);
	}
	return false;
}
@@ -152,7 +151,6 @@ static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
{
	struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
	struct i2c_adapter *adapter = dvo->i2c_bus;
	struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
	uint8_t out_buf[2];
	struct i2c_msg msg = {
		.addr = dvo->slave_addr,
@@ -164,12 +162,12 @@ static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
	out_buf[0] = addr;
	out_buf[1] = ch;

	if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1)
	if (i2c_transfer(adapter, &msg, 1) == 1)
		return true;

	if (!ch7xxx->quiet) {
		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
			  addr, i2cbus->adapter.name, dvo->slave_addr);
			  addr, adapter->name, dvo->slave_addr);
	}

	return false;
+4 −6
Original line number Diff line number Diff line
@@ -167,7 +167,6 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
{
	struct ivch_priv *priv = dvo->dev_priv;
	struct i2c_adapter *adapter = dvo->i2c_bus;
	struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
	u8 out_buf[1];
	u8 in_buf[2];

@@ -193,7 +192,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)

	out_buf[0] = addr;

	if (i2c_transfer(&i2cbus->adapter, msgs, 3) == 3) {
	if (i2c_transfer(adapter, msgs, 3) == 3) {
		*data = (in_buf[1] << 8) | in_buf[0];
		return true;
	};
@@ -201,7 +200,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
	if (!priv->quiet) {
		DRM_DEBUG_KMS("Unable to read register 0x%02x from "
				"%s:%02x.\n",
			  addr, i2cbus->adapter.name, dvo->slave_addr);
			  addr, adapter->name, dvo->slave_addr);
	}
	return false;
}
@@ -211,7 +210,6 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
{
	struct ivch_priv *priv = dvo->dev_priv;
	struct i2c_adapter *adapter = dvo->i2c_bus;
	struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
	u8 out_buf[3];
	struct i2c_msg msg = {
		.addr = dvo->slave_addr,
@@ -224,12 +222,12 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
	out_buf[1] = data & 0xff;
	out_buf[2] = data >> 8;

	if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1)
	if (i2c_transfer(adapter, &msg, 1) == 1)
		return true;

	if (!priv->quiet) {
		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
			  addr, i2cbus->adapter.name, dvo->slave_addr);
			  addr, adapter->name, dvo->slave_addr);
	}

	return false;
+4 −6
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
{
	struct sil164_priv *sil = dvo->dev_priv;
	struct i2c_adapter *adapter = dvo->i2c_bus;
	struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
	u8 out_buf[2];
	u8 in_buf[2];

@@ -91,14 +90,14 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
	out_buf[0] = addr;
	out_buf[1] = 0;

	if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) {
	if (i2c_transfer(adapter, msgs, 2) == 2) {
		*ch = in_buf[0];
		return true;
	};

	if (!sil->quiet) {
		DRM_DEBUG_KMS("Unable to read register 0x%02x from %s:%02x.\n",
			  addr, i2cbus->adapter.name, dvo->slave_addr);
			  addr, adapter->name, dvo->slave_addr);
	}
	return false;
}
@@ -107,7 +106,6 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
{
	struct sil164_priv *sil= dvo->dev_priv;
	struct i2c_adapter *adapter = dvo->i2c_bus;
	struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
	uint8_t out_buf[2];
	struct i2c_msg msg = {
		.addr = dvo->slave_addr,
@@ -119,12 +117,12 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
	out_buf[0] = addr;
	out_buf[1] = ch;

	if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1)
	if (i2c_transfer(adapter, &msg, 1) == 1)
		return true;

	if (!sil->quiet) {
		DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
			  addr, i2cbus->adapter.name, dvo->slave_addr);
			  addr, adapter->name, dvo->slave_addr);
	}

	return false;
Loading