[PATCH 1/6] drm: Add abstraction for the DP dual mode adaptor

Imre Deak imre.deak at intel.com
Wed Nov 16 20:44:05 UTC 2016


In order to apply workarounds to buggy dual mode adaptors in follow-up
patches we need a more fine-grained identification than what the adaptor
type provides. So introduce a new adaptor object and pass this to the
dual mode helpers instead of the adaptor type/i2c adapter. Device ID and
other details will be added to the object in the following patches.

Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
Cc: dri-devel at lists.freedesktop.org
Suggested-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
Signed-off-by: Imre Deak <imre.deak at intel.com>
---
 drivers/gpu/drm/drm_dp_dual_mode_helper.c | 119 ++++++++++++++++++------------
 drivers/gpu/drm/i915/intel_drv.h          |   3 +-
 drivers/gpu/drm/i915/intel_hdmi.c         |  33 ++++-----
 drivers/gpu/drm/i915/intel_lspcon.c       |  23 +++---
 include/drm/drm_dp_dual_mode_helper.h     |  38 ++++++----
 5 files changed, 125 insertions(+), 91 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/drm_dp_dual_mode_helper.c
index e025639..1764203 100644
--- a/drivers/gpu/drm/drm_dp_dual_mode_helper.c
+++ b/drivers/gpu/drm/drm_dp_dual_mode_helper.c
@@ -46,7 +46,7 @@
 
 /**
  * drm_dp_dual_mode_read - Read from the DP dual mode adaptor register(s)
- * @adapter: I2C adapter for the DDC bus
+ * @adaptor: DP dual mode adaptor
  * @offset: register offset
  * @buffer: buffer for return data
  * @size: sizo of the buffer
@@ -57,7 +57,7 @@
  * Returns:
  * 0 on success, negative error code on failure
  */
-ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
+ssize_t drm_dp_dual_mode_read(struct drm_dp_dual_mode_adaptor *adaptor,
 			      u8 offset, void *buffer, size_t size)
 {
 	struct i2c_msg msgs[] = {
@@ -76,7 +76,7 @@ ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
 	};
 	int ret;
 
-	ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
+	ret = i2c_transfer(adaptor->i2c_adapter, msgs, ARRAY_SIZE(msgs));
 	if (ret < 0)
 		return ret;
 	if (ret != ARRAY_SIZE(msgs))
@@ -88,7 +88,7 @@ EXPORT_SYMBOL(drm_dp_dual_mode_read);
 
 /**
  * drm_dp_dual_mode_write - Write to the DP dual mode adaptor register(s)
- * @adapter: I2C adapter for the DDC bus
+ * @adaptor: DP dual mode adaptor
  * @offset: register offset
  * @buffer: buffer for write data
  * @size: sizo of the buffer
@@ -99,7 +99,7 @@ EXPORT_SYMBOL(drm_dp_dual_mode_read);
  * Returns:
  * 0 on success, negative error code on failure
  */
-ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter,
+ssize_t drm_dp_dual_mode_write(struct drm_dp_dual_mode_adaptor *adaptor,
 			       u8 offset, const void *buffer, size_t size)
 {
 	struct i2c_msg msg = {
@@ -120,7 +120,7 @@ ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter,
 	memcpy(data, &offset, 1);
 	memcpy(data + 1, buffer, size);
 
-	ret = i2c_transfer(adapter, &msg, 1);
+	ret = i2c_transfer(adaptor->i2c_adapter, &msg, 1);
 
 	kfree(data);
 
@@ -163,25 +163,30 @@ static bool is_lspcon_adaptor(const char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN],
 
 /**
  * drm_dp_dual_mode_detect - Identify the DP dual mode adaptor
- * @adapter: I2C adapter for the DDC bus
+ * @adaptor: DP dual mode adaptor
+ * @i2c_adapter: I2C adapter for the DDC bus the dual mode adaptor
+ *		 is attached to
  *
  * Attempt to identify the type of the DP dual mode adaptor used.
  *
- * Note that when the answer is @DRM_DP_DUAL_MODE_UNKNOWN it's not
+ * Note that when @DRM_DP_DUAL_MODE_UNKNOWN type is detected it's not
  * certain whether we're dealing with a native HDMI port or
  * a type 1 DVI dual mode adaptor. The driver will have to use
  * some other hardware/driver specific mechanism to make that
  * distinction.
  *
- * Returns:
- * The type of the DP dual mode adaptor used
+ * On return the adaptor object will be initialized.
  */
-enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter)
+void drm_dp_dual_mode_detect(struct drm_dp_dual_mode_adaptor *adaptor,
+			     struct i2c_adapter *i2c_adapter)
 {
 	char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN] = {};
 	uint8_t adaptor_id = 0x00;
 	ssize_t ret;
 
+	adaptor->i2c_adapter = i2c_adapter;
+	adaptor->type = DRM_DP_DUAL_MODE_UNKNOWN;
+
 	/*
 	 * Let's see if the adaptor is there the by reading the
 	 * HDMI ID registers.
@@ -196,12 +201,12 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter)
 	 * port or a native HDMI port. Both of these methods are entirely
 	 * hardware/driver specific so we can't deal with them here.
 	 */
-	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_HDMI_ID,
+	ret = drm_dp_dual_mode_read(adaptor, DP_DUAL_MODE_HDMI_ID,
 				    hdmi_id, sizeof(hdmi_id));
 	DRM_DEBUG_KMS("DP dual mode HDMI ID: %*pE (err %zd)\n",
 		      ret ? 0 : (int)sizeof(hdmi_id), hdmi_id, ret);
 	if (ret)
-		return DRM_DP_DUAL_MODE_UNKNOWN;
+		return;
 
 	/*
 	 * Sigh. Some (maybe all?) type 1 adaptors are broken and ack
@@ -215,18 +220,21 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter)
 	 * the type 2 adaptor detection safely even in the presence
 	 * of broken type 1 adaptors.
 	 */
-	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID,
+	ret = drm_dp_dual_mode_read(adaptor, DP_DUAL_MODE_ADAPTOR_ID,
 				    &adaptor_id, sizeof(adaptor_id));
 	DRM_DEBUG_KMS("DP dual mode adaptor ID: %02x (err %zd)\n",
 		      adaptor_id, ret);
 	if (ret == 0) {
-		if (is_lspcon_adaptor(hdmi_id, adaptor_id))
-			return DRM_DP_DUAL_MODE_LSPCON;
+		if (is_lspcon_adaptor(hdmi_id, adaptor_id)) {
+			adaptor->type = DRM_DP_DUAL_MODE_LSPCON;
+			return;
+		}
 		if (is_type2_adaptor(adaptor_id)) {
 			if (is_hdmi_adaptor(hdmi_id))
-				return DRM_DP_DUAL_MODE_TYPE2_HDMI;
+				adaptor->type = DRM_DP_DUAL_MODE_TYPE2_HDMI;
 			else
-				return DRM_DP_DUAL_MODE_TYPE2_DVI;
+				adaptor->type = DRM_DP_DUAL_MODE_TYPE2_DVI;
+			return;
 		}
 		/*
 		 * If neither a proper type 1 ID nor a broken type 1 adaptor
@@ -240,16 +248,39 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter)
 	}
 
 	if (is_hdmi_adaptor(hdmi_id))
-		return DRM_DP_DUAL_MODE_TYPE1_HDMI;
+		adaptor->type = DRM_DP_DUAL_MODE_TYPE1_HDMI;
 	else
-		return DRM_DP_DUAL_MODE_TYPE1_DVI;
+		adaptor->type = DRM_DP_DUAL_MODE_TYPE1_DVI;
 }
 EXPORT_SYMBOL(drm_dp_dual_mode_detect);
 
 /**
+ * drm_dp_dual_mode_set_type - Set DP dual mode adaptor type
+ * @adaptor: DP dual mode adaptor
+ * @type: New type to set
+ *
+ * Set a new type for the adaptor, reinitializing the adaptor object as
+ * needed. This can be used by platform specific code to change the adaptor
+ * type from what drm_dp_dual_mode_detect() detected or to deinitialize the
+ * object when not in use any more by passing @DRM_DP_DUAL_MODE_NONE.
+ */
+void drm_dp_dual_mode_set_type(struct drm_dp_dual_mode_adaptor *adaptor,
+			       enum drm_dp_dual_mode_type type)
+{
+	if (type == DRM_DP_DUAL_MODE_NONE) {
+		memset(adaptor, 0, sizeof(*adaptor));
+		return;
+	}
+
+	/* Setting a type other than NONE is only valid after a detect call. */
+	WARN_ON(adaptor->type == DRM_DP_DUAL_MODE_NONE);
+	adaptor->type = type;
+}
+EXPORT_SYMBOL(drm_dp_dual_mode_set_type);
+
+/**
  * drm_dp_dual_mode_max_tmds_clock - Max TMDS clock for DP dual mode adaptor
- * @type: DP dual mode adaptor type
- * @adapter: I2C adapter for the DDC bus
+ * @adaptor: DP dual mode adaptor
  *
  * Determine the max TMDS clock the adaptor supports based on the
  * type of the dual mode adaptor and the DP_DUAL_MODE_MAX_TMDS_CLOCK
@@ -261,24 +292,23 @@ EXPORT_SYMBOL(drm_dp_dual_mode_detect);
  * Returns:
  * Maximum supported TMDS clock rate for the DP dual mode adaptor in kHz.
  */
-int drm_dp_dual_mode_max_tmds_clock(enum drm_dp_dual_mode_type type,
-				    struct i2c_adapter *adapter)
+int drm_dp_dual_mode_max_tmds_clock(struct drm_dp_dual_mode_adaptor *adaptor)
 {
 	uint8_t max_tmds_clock;
 	ssize_t ret;
 
 	/* native HDMI so no limit */
-	if (type == DRM_DP_DUAL_MODE_NONE)
+	if (adaptor->type == DRM_DP_DUAL_MODE_NONE)
 		return 0;
 
 	/*
 	 * Type 1 adaptors are limited to 165MHz
 	 * Type 2 adaptors can tells us their limit
 	 */
-	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
+	if (adaptor->type < DRM_DP_DUAL_MODE_TYPE2_DVI)
 		return 165000;
 
-	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_MAX_TMDS_CLOCK,
+	ret = drm_dp_dual_mode_read(adaptor, DP_DUAL_MODE_MAX_TMDS_CLOCK,
 				    &max_tmds_clock, sizeof(max_tmds_clock));
 	if (ret || max_tmds_clock == 0x00 || max_tmds_clock == 0xff) {
 		DRM_DEBUG_KMS("Failed to query max TMDS clock\n");
@@ -291,8 +321,7 @@ EXPORT_SYMBOL(drm_dp_dual_mode_max_tmds_clock);
 
 /**
  * drm_dp_dual_mode_get_tmds_output - Get the state of the TMDS output buffers in the DP dual mode adaptor
- * @type: DP dual mode adaptor type
- * @adapter: I2C adapter for the DDC bus
+ * @adaptor: DP dual mode adaptor
  * @enabled: current state of the TMDS output buffers
  *
  * Get the state of the TMDS output buffers in the adaptor. For
@@ -305,19 +334,18 @@ EXPORT_SYMBOL(drm_dp_dual_mode_max_tmds_clock);
  * Returns:
  * 0 on success, negative error code on failure
  */
-int drm_dp_dual_mode_get_tmds_output(enum drm_dp_dual_mode_type type,
-				     struct i2c_adapter *adapter,
+int drm_dp_dual_mode_get_tmds_output(struct drm_dp_dual_mode_adaptor *adaptor,
 				     bool *enabled)
 {
 	uint8_t tmds_oen;
 	ssize_t ret;
 
-	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI) {
+	if (adaptor->type < DRM_DP_DUAL_MODE_TYPE2_DVI) {
 		*enabled = true;
 		return 0;
 	}
 
-	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
+	ret = drm_dp_dual_mode_read(adaptor, DP_DUAL_MODE_TMDS_OEN,
 				    &tmds_oen, sizeof(tmds_oen));
 	if (ret) {
 		DRM_DEBUG_KMS("Failed to query state of TMDS output buffers\n");
@@ -332,8 +360,7 @@ EXPORT_SYMBOL(drm_dp_dual_mode_get_tmds_output);
 
 /**
  * drm_dp_dual_mode_set_tmds_output - Enable/disable TMDS output buffers in the DP dual mode adaptor
- * @type: DP dual mode adaptor type
- * @adapter: I2C adapter for the DDC bus
+ * @adaptor: DP dual mode adaptor
  * @enable: enable (as opposed to disable) the TMDS output buffers
  *
  * Set the state of the TMDS output buffers in the adaptor. For
@@ -345,16 +372,16 @@ EXPORT_SYMBOL(drm_dp_dual_mode_get_tmds_output);
  * Returns:
  * 0 on success, negative error code on failure
  */
-int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
-				     struct i2c_adapter *adapter, bool enable)
+int drm_dp_dual_mode_set_tmds_output(struct drm_dp_dual_mode_adaptor *adaptor,
+				     bool enable)
 {
 	uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
 	ssize_t ret;
 
-	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
+	if (adaptor->type < DRM_DP_DUAL_MODE_TYPE2_DVI)
 		return 0;
 
-	ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
+	ret = drm_dp_dual_mode_write(adaptor, DP_DUAL_MODE_TMDS_OEN,
 				     &tmds_oen, sizeof(tmds_oen));
 	if (ret) {
 		DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
@@ -396,14 +423,14 @@ EXPORT_SYMBOL(drm_dp_get_dual_mode_type_name);
 /**
  * drm_lspcon_get_mode: Get LSPCON's current mode of operation by
  * reading offset (0x80, 0x41)
- * @adapter: I2C-over-aux adapter
+ * @adaptor: DP dual mode adaptor
  * @mode: current lspcon mode of operation output variable
  *
  * Returns:
  * 0 on success, sets the current_mode value to appropriate mode
  * -error on failure
  */
-int drm_lspcon_get_mode(struct i2c_adapter *adapter,
+int drm_lspcon_get_mode(struct drm_dp_dual_mode_adaptor *adaptor,
 			enum drm_lspcon_mode *mode)
 {
 	u8 data;
@@ -415,7 +442,7 @@ int drm_lspcon_get_mode(struct i2c_adapter *adapter,
 	}
 
 	/* Read Status: i2c over aux */
-	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_LSPCON_CURRENT_MODE,
+	ret = drm_dp_dual_mode_read(adaptor, DP_DUAL_MODE_LSPCON_CURRENT_MODE,
 				    &data, sizeof(data));
 	if (ret < 0) {
 		DRM_ERROR("LSPCON read(0x80, 0x41) failed\n");
@@ -433,13 +460,13 @@ EXPORT_SYMBOL(drm_lspcon_get_mode);
 /**
  * drm_lspcon_set_mode: Change LSPCON's mode of operation by
  * writing offset (0x80, 0x40)
- * @adapter: I2C-over-aux adapter
+ * @adaptor: DP dual mode adaptor
  * @mode: required mode of operation
  *
  * Returns:
  * 0 on success, -error on failure/timeout
  */
-int drm_lspcon_set_mode(struct i2c_adapter *adapter,
+int drm_lspcon_set_mode(struct drm_dp_dual_mode_adaptor *adaptor,
 			enum drm_lspcon_mode mode)
 {
 	u8 data = 0;
@@ -451,7 +478,7 @@ int drm_lspcon_set_mode(struct i2c_adapter *adapter,
 		data = DP_DUAL_MODE_LSPCON_MODE_PCON;
 
 	/* Change mode */
-	ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_LSPCON_MODE_CHANGE,
+	ret = drm_dp_dual_mode_write(adaptor, DP_DUAL_MODE_LSPCON_MODE_CHANGE,
 				     &data, sizeof(data));
 	if (ret < 0) {
 		DRM_ERROR("LSPCON mode change failed\n");
@@ -464,7 +491,7 @@ int drm_lspcon_set_mode(struct i2c_adapter *adapter,
 	 * so wait and retry until time out or done.
 	 */
 	do {
-		ret = drm_lspcon_get_mode(adapter, &current_mode);
+		ret = drm_lspcon_get_mode(adaptor, &current_mode);
 		if (ret) {
 			DRM_ERROR("can't confirm LSPCON mode change\n");
 			return ret;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 75252ec..9bdd635 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -827,8 +827,8 @@ struct cxsr_latency {
 struct intel_hdmi {
 	i915_reg_t hdmi_reg;
 	int ddc_bus;
+	struct drm_dp_dual_mode_adaptor dual_mode_adaptor;
 	struct {
-		enum drm_dp_dual_mode_type type;
 		int max_tmds_clock;
 	} dp_dual_mode;
 	bool limited_color_range;
@@ -964,6 +964,7 @@ struct intel_lspcon {
 	bool active;
 	enum drm_lspcon_mode mode;
 	bool desc_valid;
+	struct drm_dp_dual_mode_adaptor dual_mode_adaptor;
 };
 
 struct intel_digital_port {
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index fb88e32..b6ee3a8 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -838,18 +838,13 @@ static void hsw_set_infoframes(struct drm_encoder *encoder,
 
 void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
 {
-	struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi));
-	struct i2c_adapter *adapter =
-		intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
-
-	if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
+	if (hdmi->dual_mode_adaptor.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
 		return;
 
 	DRM_DEBUG_KMS("%s DP dual mode adaptor TMDS output\n",
 		      enable ? "Enabling" : "Disabling");
 
-	drm_dp_dual_mode_set_tmds_output(hdmi->dp_dual_mode.type,
-					 adapter, enable);
+	drm_dp_dual_mode_set_tmds_output(&hdmi->dual_mode_adaptor, enable);
 }
 
 static void intel_hdmi_prepare(struct intel_encoder *encoder)
@@ -1392,7 +1387,8 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
 	intel_hdmi->has_audio = false;
 	intel_hdmi->rgb_quant_range_selectable = false;
 
-	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
+	drm_dp_dual_mode_set_type(&intel_hdmi->dual_mode_adaptor,
+				  DRM_DP_DUAL_MODE_NONE);
 	intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
 
 	kfree(to_intel_connector(connector)->detect_edid);
@@ -1405,9 +1401,10 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *hdmi = intel_attached_hdmi(connector);
 	enum port port = hdmi_to_dig_port(hdmi)->port;
-	struct i2c_adapter *adapter =
+	struct i2c_adapter *i2c_adapter =
 		intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
-	enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter);
+	struct drm_dp_dual_mode_adaptor *dual_mode_adaptor =
+		&hdmi->dual_mode_adaptor;
 
 	/*
 	 * Type 1 DVI adaptors are not required to implement any
@@ -1421,25 +1418,27 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
 	 * confusing log messages about DP dual mode adaptors when
 	 * there's nothing connected to the port.
 	 */
-	if (type == DRM_DP_DUAL_MODE_UNKNOWN) {
+	drm_dp_dual_mode_detect(dual_mode_adaptor, i2c_adapter);
+	if (dual_mode_adaptor->type == DRM_DP_DUAL_MODE_UNKNOWN) {
 		if (has_edid &&
 		    intel_bios_is_port_dp_dual_mode(dev_priv, port)) {
 			DRM_DEBUG_KMS("Assuming DP dual mode adaptor presence based on VBT\n");
-			type = DRM_DP_DUAL_MODE_TYPE1_DVI;
+			drm_dp_dual_mode_set_type(dual_mode_adaptor,
+						  DRM_DP_DUAL_MODE_TYPE1_DVI);
 		} else {
-			type = DRM_DP_DUAL_MODE_NONE;
+			drm_dp_dual_mode_set_type(dual_mode_adaptor,
+						  DRM_DP_DUAL_MODE_NONE);
 		}
 	}
 
-	if (type == DRM_DP_DUAL_MODE_NONE)
+	if (dual_mode_adaptor->type == DRM_DP_DUAL_MODE_NONE)
 		return;
 
-	hdmi->dp_dual_mode.type = type;
 	hdmi->dp_dual_mode.max_tmds_clock =
-		drm_dp_dual_mode_max_tmds_clock(type, adapter);
+		drm_dp_dual_mode_max_tmds_clock(dual_mode_adaptor);
 
 	DRM_DEBUG_KMS("DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
-		      drm_dp_get_dual_mode_type_name(type),
+		      drm_dp_get_dual_mode_type_name(dual_mode_adaptor->type),
 		      hdmi->dp_dual_mode.max_tmds_clock);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c
index daa5234..d75ca05 100644
--- a/drivers/gpu/drm/i915/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/intel_lspcon.c
@@ -38,9 +38,8 @@ static struct intel_dp *lspcon_to_intel_dp(struct intel_lspcon *lspcon)
 static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon)
 {
 	enum drm_lspcon_mode current_mode = DRM_LSPCON_MODE_INVALID;
-	struct i2c_adapter *adapter = &lspcon_to_intel_dp(lspcon)->aux.ddc;
 
-	if (drm_lspcon_get_mode(adapter, &current_mode))
+	if (drm_lspcon_get_mode(&lspcon->dual_mode_adaptor, &current_mode))
 		DRM_ERROR("Error reading LSPCON mode\n");
 	else
 		DRM_DEBUG_KMS("Current LSPCON mode %s\n",
@@ -49,13 +48,14 @@ static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon)
 }
 
 static int lspcon_change_mode(struct intel_lspcon *lspcon,
-	enum drm_lspcon_mode mode, bool force)
+			      enum drm_lspcon_mode mode, bool force)
 {
 	int err;
 	enum drm_lspcon_mode current_mode;
-	struct i2c_adapter *adapter = &lspcon_to_intel_dp(lspcon)->aux.ddc;
+	struct drm_dp_dual_mode_adaptor *dual_mode_adaptor =
+		&lspcon->dual_mode_adaptor;
 
-	err = drm_lspcon_get_mode(adapter, &current_mode);
+	err = drm_lspcon_get_mode(dual_mode_adaptor, &current_mode);
 	if (err) {
 		DRM_ERROR("Error reading LSPCON mode\n");
 		return err;
@@ -66,7 +66,7 @@ static int lspcon_change_mode(struct intel_lspcon *lspcon,
 		return 0;
 	}
 
-	err = drm_lspcon_set_mode(adapter, mode);
+	err = drm_lspcon_set_mode(dual_mode_adaptor, mode);
 	if (err < 0) {
 		DRM_ERROR("LSPCON mode change failed\n");
 		return err;
@@ -79,14 +79,15 @@ static int lspcon_change_mode(struct intel_lspcon *lspcon,
 
 static bool lspcon_probe(struct intel_lspcon *lspcon)
 {
-	enum drm_dp_dual_mode_type adaptor_type;
-	struct i2c_adapter *adapter = &lspcon_to_intel_dp(lspcon)->aux.ddc;
+	struct i2c_adapter *i2c_adapter = &lspcon_to_intel_dp(lspcon)->aux.ddc;
+	struct drm_dp_dual_mode_adaptor *dual_mode_adaptor =
+		&lspcon->dual_mode_adaptor;
 
 	/* Lets probe the adaptor and check its type */
-	adaptor_type = drm_dp_dual_mode_detect(adapter);
-	if (adaptor_type != DRM_DP_DUAL_MODE_LSPCON) {
+	drm_dp_dual_mode_detect(dual_mode_adaptor, i2c_adapter);
+	if (dual_mode_adaptor->type != DRM_DP_DUAL_MODE_LSPCON) {
 		DRM_DEBUG_KMS("No LSPCON detected, found %s\n",
-			drm_dp_get_dual_mode_type_name(adaptor_type));
+			drm_dp_get_dual_mode_type_name(dual_mode_adaptor->type));
 		return false;
 	}
 
diff --git a/include/drm/drm_dp_dual_mode_helper.h b/include/drm/drm_dp_dual_mode_helper.h
index 4c42db8..a804d36 100644
--- a/include/drm/drm_dp_dual_mode_helper.h
+++ b/include/drm/drm_dp_dual_mode_helper.h
@@ -62,13 +62,6 @@
 #define DP_DUAL_MODE_LSPCON_CURRENT_MODE		0x41
 #define  DP_DUAL_MODE_LSPCON_MODE_PCON			0x1
 
-struct i2c_adapter;
-
-ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
-			      u8 offset, void *buffer, size_t size);
-ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter,
-			       u8 offset, const void *buffer, size_t size);
-
 /**
  * enum drm_lspcon_mode
  * @DRM_LSPCON_MODE_INVALID: No LSPCON.
@@ -103,17 +96,30 @@ enum drm_dp_dual_mode_type {
 	DRM_DP_DUAL_MODE_LSPCON,
 };
 
-enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter);
-int drm_dp_dual_mode_max_tmds_clock(enum drm_dp_dual_mode_type type,
-				    struct i2c_adapter *adapter);
-int drm_dp_dual_mode_get_tmds_output(enum drm_dp_dual_mode_type type,
-				     struct i2c_adapter *adapter, bool *enabled);
-int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
-				     struct i2c_adapter *adapter, bool enable);
+struct i2c_adapter;
+
+struct drm_dp_dual_mode_adaptor {
+	enum drm_dp_dual_mode_type type;
+	struct i2c_adapter *i2c_adapter;
+};
+
+void drm_dp_dual_mode_detect(struct drm_dp_dual_mode_adaptor *adaptor,
+			     struct i2c_adapter *i2c_adapter);
+void drm_dp_dual_mode_set_type(struct drm_dp_dual_mode_adaptor *adaptor,
+			       enum drm_dp_dual_mode_type type);
+ssize_t drm_dp_dual_mode_read(struct drm_dp_dual_mode_adaptor *adaptor,
+			      u8 offset, void *buffer, size_t size);
+ssize_t drm_dp_dual_mode_write(struct drm_dp_dual_mode_adaptor *adaptor,
+			       u8 offset, const void *buffer, size_t size);
+int drm_dp_dual_mode_max_tmds_clock(struct drm_dp_dual_mode_adaptor *adaptor);
+int drm_dp_dual_mode_get_tmds_output(struct drm_dp_dual_mode_adaptor *adaptor,
+				     bool *enabled);
+int drm_dp_dual_mode_set_tmds_output(struct drm_dp_dual_mode_adaptor *adaptor,
+				     bool enable);
 const char *drm_dp_get_dual_mode_type_name(enum drm_dp_dual_mode_type type);
 
-int drm_lspcon_get_mode(struct i2c_adapter *adapter,
+int drm_lspcon_get_mode(struct drm_dp_dual_mode_adaptor *adaptor,
 			enum drm_lspcon_mode *current_mode);
-int drm_lspcon_set_mode(struct i2c_adapter *adapter,
+int drm_lspcon_set_mode(struct drm_dp_dual_mode_adaptor *adaptor,
 			enum drm_lspcon_mode reqd_mode);
 #endif
-- 
2.5.0



More information about the Intel-gfx-trybot mailing list