|
@@ -57,7 +57,9 @@ struct apple_gmux_data {
|
|
/* switcheroo data */
|
|
/* switcheroo data */
|
|
acpi_handle dhandle;
|
|
acpi_handle dhandle;
|
|
int gpe;
|
|
int gpe;
|
|
- enum vga_switcheroo_client_id resume_client_id;
|
|
|
|
|
|
+ enum vga_switcheroo_client_id switch_state_display;
|
|
|
|
+ enum vga_switcheroo_client_id switch_state_ddc;
|
|
|
|
+ enum vga_switcheroo_client_id switch_state_external;
|
|
enum vga_switcheroo_state power_state;
|
|
enum vga_switcheroo_state power_state;
|
|
struct completion powerchange_done;
|
|
struct completion powerchange_done;
|
|
};
|
|
};
|
|
@@ -368,17 +370,49 @@ static const struct backlight_ops gmux_bl_ops = {
|
|
* for the selected GPU.
|
|
* for the selected GPU.
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+static void gmux_read_switch_state(struct apple_gmux_data *gmux_data)
|
|
|
|
+{
|
|
|
|
+ if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DDC) == 1)
|
|
|
|
+ gmux_data->switch_state_ddc = VGA_SWITCHEROO_IGD;
|
|
|
|
+ else
|
|
|
|
+ gmux_data->switch_state_ddc = VGA_SWITCHEROO_DIS;
|
|
|
|
+
|
|
|
|
+ if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2)
|
|
|
|
+ gmux_data->switch_state_display = VGA_SWITCHEROO_IGD;
|
|
|
|
+ else
|
|
|
|
+ gmux_data->switch_state_display = VGA_SWITCHEROO_DIS;
|
|
|
|
+
|
|
|
|
+ if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL) == 2)
|
|
|
|
+ gmux_data->switch_state_external = VGA_SWITCHEROO_IGD;
|
|
|
|
+ else
|
|
|
|
+ gmux_data->switch_state_external = VGA_SWITCHEROO_DIS;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void gmux_write_switch_state(struct apple_gmux_data *gmux_data)
|
|
|
|
+{
|
|
|
|
+ if (gmux_data->switch_state_ddc == VGA_SWITCHEROO_IGD)
|
|
|
|
+ gmux_write8(gmux_data, GMUX_PORT_SWITCH_DDC, 1);
|
|
|
|
+ else
|
|
|
|
+ gmux_write8(gmux_data, GMUX_PORT_SWITCH_DDC, 2);
|
|
|
|
+
|
|
|
|
+ if (gmux_data->switch_state_display == VGA_SWITCHEROO_IGD)
|
|
|
|
+ gmux_write8(gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2);
|
|
|
|
+ else
|
|
|
|
+ gmux_write8(gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3);
|
|
|
|
+
|
|
|
|
+ if (gmux_data->switch_state_external == VGA_SWITCHEROO_IGD)
|
|
|
|
+ gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2);
|
|
|
|
+ else
|
|
|
|
+ gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3);
|
|
|
|
+}
|
|
|
|
+
|
|
static int gmux_switchto(enum vga_switcheroo_client_id id)
|
|
static int gmux_switchto(enum vga_switcheroo_client_id id)
|
|
{
|
|
{
|
|
- if (id == VGA_SWITCHEROO_IGD) {
|
|
|
|
- gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1);
|
|
|
|
- gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2);
|
|
|
|
- gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2);
|
|
|
|
- } else {
|
|
|
|
- gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2);
|
|
|
|
- gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3);
|
|
|
|
- gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3);
|
|
|
|
- }
|
|
|
|
|
|
+ apple_gmux_data->switch_state_ddc = id;
|
|
|
|
+ apple_gmux_data->switch_state_display = id;
|
|
|
|
+ apple_gmux_data->switch_state_external = id;
|
|
|
|
+
|
|
|
|
+ gmux_write_switch_state(apple_gmux_data);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -440,15 +474,6 @@ static int gmux_get_client_id(struct pci_dev *pdev)
|
|
return VGA_SWITCHEROO_DIS;
|
|
return VGA_SWITCHEROO_DIS;
|
|
}
|
|
}
|
|
|
|
|
|
-static enum vga_switcheroo_client_id
|
|
|
|
-gmux_active_client(struct apple_gmux_data *gmux_data)
|
|
|
|
-{
|
|
|
|
- if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2)
|
|
|
|
- return VGA_SWITCHEROO_IGD;
|
|
|
|
-
|
|
|
|
- return VGA_SWITCHEROO_DIS;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static const struct vga_switcheroo_handler gmux_handler = {
|
|
static const struct vga_switcheroo_handler gmux_handler = {
|
|
.switchto = gmux_switchto,
|
|
.switchto = gmux_switchto,
|
|
.power_state = gmux_set_power_state,
|
|
.power_state = gmux_set_power_state,
|
|
@@ -513,7 +538,6 @@ static int gmux_suspend(struct device *dev)
|
|
struct pnp_dev *pnp = to_pnp_dev(dev);
|
|
struct pnp_dev *pnp = to_pnp_dev(dev);
|
|
struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
|
|
struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
|
|
|
|
|
|
- gmux_data->resume_client_id = gmux_active_client(gmux_data);
|
|
|
|
gmux_disable_interrupts(gmux_data);
|
|
gmux_disable_interrupts(gmux_data);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -524,7 +548,7 @@ static int gmux_resume(struct device *dev)
|
|
struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
|
|
struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
|
|
|
|
|
|
gmux_enable_interrupts(gmux_data);
|
|
gmux_enable_interrupts(gmux_data);
|
|
- gmux_switchto(gmux_data->resume_client_id);
|
|
|
|
|
|
+ gmux_write_switch_state(gmux_data);
|
|
if (gmux_data->power_state == VGA_SWITCHEROO_OFF)
|
|
if (gmux_data->power_state == VGA_SWITCHEROO_OFF)
|
|
gmux_set_discrete_state(gmux_data, gmux_data->power_state);
|
|
gmux_set_discrete_state(gmux_data, gmux_data->power_state);
|
|
return 0;
|
|
return 0;
|
|
@@ -704,6 +728,7 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
|
|
apple_gmux_data = gmux_data;
|
|
apple_gmux_data = gmux_data;
|
|
init_completion(&gmux_data->powerchange_done);
|
|
init_completion(&gmux_data->powerchange_done);
|
|
gmux_enable_interrupts(gmux_data);
|
|
gmux_enable_interrupts(gmux_data);
|
|
|
|
+ gmux_read_switch_state(gmux_data);
|
|
|
|
|
|
if (vga_switcheroo_register_handler(&gmux_handler, 0)) {
|
|
if (vga_switcheroo_register_handler(&gmux_handler, 0)) {
|
|
ret = -ENODEV;
|
|
ret = -ENODEV;
|