|
@@ -417,6 +417,25 @@ static int gmux_switchto(enum vga_switcheroo_client_id id)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int gmux_switch_ddc(enum vga_switcheroo_client_id id)
|
|
|
+{
|
|
|
+ enum vga_switcheroo_client_id old_ddc_owner =
|
|
|
+ apple_gmux_data->switch_state_ddc;
|
|
|
+
|
|
|
+ if (id == old_ddc_owner)
|
|
|
+ return id;
|
|
|
+
|
|
|
+ pr_debug("Switching DDC from %d to %d\n", old_ddc_owner, id);
|
|
|
+ apple_gmux_data->switch_state_ddc = id;
|
|
|
+
|
|
|
+ if (id == VGA_SWITCHEROO_IGD)
|
|
|
+ gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1);
|
|
|
+ else
|
|
|
+ gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2);
|
|
|
+
|
|
|
+ return old_ddc_owner;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* DOC: Power control
|
|
|
*
|
|
@@ -474,12 +493,19 @@ static int gmux_get_client_id(struct pci_dev *pdev)
|
|
|
return VGA_SWITCHEROO_DIS;
|
|
|
}
|
|
|
|
|
|
-static const struct vga_switcheroo_handler gmux_handler = {
|
|
|
+static const struct vga_switcheroo_handler gmux_handler_indexed = {
|
|
|
.switchto = gmux_switchto,
|
|
|
.power_state = gmux_set_power_state,
|
|
|
.get_client_id = gmux_get_client_id,
|
|
|
};
|
|
|
|
|
|
+static const struct vga_switcheroo_handler gmux_handler_classic = {
|
|
|
+ .switchto = gmux_switchto,
|
|
|
+ .switch_ddc = gmux_switch_ddc,
|
|
|
+ .power_state = gmux_set_power_state,
|
|
|
+ .get_client_id = gmux_get_client_id,
|
|
|
+};
|
|
|
+
|
|
|
/**
|
|
|
* DOC: Interrupt
|
|
|
*
|
|
@@ -730,8 +756,21 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
|
|
|
gmux_enable_interrupts(gmux_data);
|
|
|
gmux_read_switch_state(gmux_data);
|
|
|
|
|
|
- if (vga_switcheroo_register_handler(&gmux_handler, 0)) {
|
|
|
- ret = -ENODEV;
|
|
|
+ /*
|
|
|
+ * Retina MacBook Pros cannot switch the panel's AUX separately
|
|
|
+ * and need eDP pre-calibration. They are distinguishable from
|
|
|
+ * pre-retinas by having an "indexed" gmux.
|
|
|
+ *
|
|
|
+ * Pre-retina MacBook Pros can switch the panel's DDC separately.
|
|
|
+ */
|
|
|
+ if (gmux_data->indexed)
|
|
|
+ ret = vga_switcheroo_register_handler(&gmux_handler_indexed,
|
|
|
+ VGA_SWITCHEROO_NEEDS_EDP_CONFIG);
|
|
|
+ else
|
|
|
+ ret = vga_switcheroo_register_handler(&gmux_handler_classic,
|
|
|
+ VGA_SWITCHEROO_CAN_SWITCH_DDC);
|
|
|
+ if (ret) {
|
|
|
+ pr_err("Failed to register vga_switcheroo handler\n");
|
|
|
goto err_register_handler;
|
|
|
}
|
|
|
|