|
@@ -462,14 +462,63 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Don't check status code from this as it switches the bus back to the
|
|
|
- * SDVO chips which defeats the purpose of doing a bus switch in the first
|
|
|
- * place.
|
|
|
+ * Try to read the response after issuie the DDC switch command. But it
|
|
|
+ * is noted that we must do the action of reading response and issuing DDC
|
|
|
+ * switch command in one I2C transaction. Otherwise when we try to start
|
|
|
+ * another I2C transaction after issuing the DDC bus switch, it will be
|
|
|
+ * switched to the internal SDVO register.
|
|
|
*/
|
|
|
static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
|
|
|
u8 target)
|
|
|
{
|
|
|
- intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
|
|
|
+ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
|
|
|
+ u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
|
|
|
+ struct i2c_msg msgs[] = {
|
|
|
+ {
|
|
|
+ .addr = sdvo_priv->slave_addr >> 1,
|
|
|
+ .flags = 0,
|
|
|
+ .len = 2,
|
|
|
+ .buf = out_buf,
|
|
|
+ },
|
|
|
+ /* the following two are to read the response */
|
|
|
+ {
|
|
|
+ .addr = sdvo_priv->slave_addr >> 1,
|
|
|
+ .flags = 0,
|
|
|
+ .len = 1,
|
|
|
+ .buf = cmd_buf,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .addr = sdvo_priv->slave_addr >> 1,
|
|
|
+ .flags = I2C_M_RD,
|
|
|
+ .len = 1,
|
|
|
+ .buf = ret_value,
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
|
|
|
+ &target, 1);
|
|
|
+ /* write the DDC switch command argument */
|
|
|
+ intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target);
|
|
|
+
|
|
|
+ out_buf[0] = SDVO_I2C_OPCODE;
|
|
|
+ out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
|
|
|
+ cmd_buf[0] = SDVO_I2C_CMD_STATUS;
|
|
|
+ cmd_buf[1] = 0;
|
|
|
+ ret_value[0] = 0;
|
|
|
+ ret_value[1] = 0;
|
|
|
+
|
|
|
+ ret = i2c_transfer(intel_output->i2c_bus, msgs, 3);
|
|
|
+ if (ret != 3) {
|
|
|
+ /* failure in I2C transfer */
|
|
|
+ DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (ret_value[0] != SDVO_CMD_STATUS_SUCCESS) {
|
|
|
+ DRM_DEBUG_KMS("DDC switch command returns response %d\n",
|
|
|
+ ret_value[0]);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
|