Skip to content

Commit

Permalink
surface_acpi: Update based on module
Browse files Browse the repository at this point in the history
- Enable performance modes on Pro 5/6/7 and Laptop 3
- Fix some checkpatch warnings and whitespace issues
  • Loading branch information
qzed authored and StollD committed Mar 30, 2020
1 parent 08e8fc4 commit fa33900
Show file tree
Hide file tree
Showing 13 changed files with 348 additions and 409 deletions.
44 changes: 22 additions & 22 deletions drivers/platform/x86/surface_sam/Kconfig
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
menuconfig SURFACE_SAM
depends on ACPI
tristate "Microsoft Surface/System Aggregator Module and Platform Drivers"
---help---
Drivers for the Surface/System Aggregator Module (SAM) of Microsoft
Surface devices.
depends on ACPI
tristate "Microsoft Surface/System Aggregator Module and Platform Drivers"
help
Drivers for the Surface/System Aggregator Module (SAM) of Microsoft
Surface devices.

SAM is an embedded controller that provides access to various
functionalities on these devices, including battery status, keyboard
events (on the Laptops) and many more.
SAM is an embedded controller that provides access to various
functionalities on these devices, including battery status, keyboard
events (on the Laptops) and many more.

Say M/Y here if you have a Microsoft Surface device with a SAM device
(i.e. 5th generation or later).
Say M/Y here if you have a Microsoft Surface device with a SAM device
(i.e. 5th generation or later).

config SURFACE_SAM_SSH
tristate "Surface Serial Hub Driver"
depends on SURFACE_SAM
depends on SERIAL_DEV_CTRL_TTYPORT
select CRC_CCITT
default m
---help---
help
Surface Serial Hub driver for 5th generation (or later) Microsoft
Surface devices.

Expand All @@ -36,7 +36,7 @@ config SURFACE_SAM_SSH_DEBUG_DEVICE
depends on SURFACE_SAM_SSH
depends on SYSFS
default n
---help---
help
Debug device for direct communication with the embedded controller
found on 5th generation (and later) Microsoft Surface devices (e.g.
Book 2, Laptop, Laptop 2, Pro 2017, Pro 6, ...) via sysfs.
Expand All @@ -47,7 +47,7 @@ config SURFACE_SAM_SAN
tristate "Surface ACPI Notify Driver"
depends on SURFACE_SAM_SSH
default m
---help---
help
Surface ACPI Notify driver for 5th generation (or later) Microsoft
Surface devices.

Expand All @@ -62,7 +62,7 @@ config SURFACE_SAM_VHF
depends on SURFACE_SAM_SSH
depends on HID
default m
---help---
help
Surface Virtual HID Framework driver for 5th generation (or later)
Microsoft Surface devices.

Expand All @@ -76,7 +76,7 @@ config SURFACE_SAM_DTX
depends on SURFACE_SAM_SSH
depends on INPUT
default m
---help---
help
Surface Detachment System (DTX) driver for the Microsoft Surface Book
2. This driver provides support for proper detachment handling in
user-space, status-events relating to the base and support for
Expand All @@ -94,7 +94,7 @@ config SURFACE_SAM_HPS
depends on SURFACE_SAM_SAN
depends on GPIO_SYSFS
default m
---help---
help
Driver to properly handle hot-plugging and explicit power-on/power-off
of the discrete GPU (dGPU) on the Surface Book 2.

Expand All @@ -104,7 +104,7 @@ config SURFACE_SAM_SID
tristate "Surface Platform Integration Driver"
depends on SURFACE_SAM_SSH
default m
---help---
help
Surface Platform Integration Driver for the Microsoft Surface Devices.
This driver loads various model-specific sub-drivers, including
battery and keyboard support on 7th generation Surface devices, proper
Expand All @@ -118,7 +118,7 @@ config SURFACE_SAM_SID_GPELID
tristate "Surface Lid Wakeup Driver"
depends on SURFACE_SAM_SID
default m
---help---
help
Driver to set up device wake-up via lid on Intel-based Microsoft
Surface devices. These devices do not wake up from sleep as their GPE
interrupt is not configured automatically. This driver solves that
Expand All @@ -131,8 +131,8 @@ config SURFACE_SAM_SID_PERFMODE
depends on SURFACE_SAM_SID
depends on SYSFS
default m
---help---
This driver provides suport for setting performance-modes on Surface
help
This driver provides support for setting performance-modes on Surface
devices via the perf_mode sysfs attribute. Currently only supports the
Surface Book 2. Performance-modes directly influence the fan-profile
of the device, allowing to choose between higher performance or
Expand All @@ -145,7 +145,7 @@ config SURFACE_SAM_SID_VHF
depends on SURFACE_SAM_SID
depends on HID
default m
---help---
help
This driver provides support for HID devices connected via the Surface
SAM embedded controller. It provides support for keyboard and touchpad
on the Surface Laptop 3 models.
Expand All @@ -157,7 +157,7 @@ config SURFACE_SAM_SID_POWER
depends on SURFACE_SAM_SID
select POWER_SUPPLY
default m
---help---
help
This driver provides support for the battery and AC on 7th generation
Surface devices.

Expand Down
81 changes: 31 additions & 50 deletions drivers/platform/x86/surface_sam/surface_sam_dtx.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Detachment system (DTX) driver for Microsoft Surface Book 2.
*/
Expand Down Expand Up @@ -117,13 +118,11 @@ static int surface_sam_query_opmpde(void)
};

status = surface_sam_ssh_rqst(&rqst, &result);
if (status) {
if (status)
return status;
}

if (result.len != 1) {
if (result.len != 1)
return -EFAULT;
}

return result.data[0];
}
Expand All @@ -146,14 +145,14 @@ static int dtx_cmd_simple(u8 cid)

static int dtx_cmd_get_opmode(int __user *buf)
{
int opmode = surface_sam_query_opmpde();
if (opmode < 0) {
int opmode;

opmode = surface_sam_query_opmpde();
if (opmode < 0)
return opmode;
}

if (put_user(opmode, buf)) {
if (put_user(opmode, buf))
return -EACCES;
}

return 0;
}
Expand All @@ -166,9 +165,8 @@ static int surface_dtx_open(struct inode *inode, struct file *file)

// initialize client
client = kzalloc(sizeof(struct surface_dtx_client), GFP_KERNEL);
if (!client) {
if (!client)
return -ENOMEM;
}

spin_lock_init(&client->buffer_lock);
client->buffer_head = 0;
Expand Down Expand Up @@ -210,37 +208,32 @@ static ssize_t surface_dtx_read(struct file *file, char __user *buf, size_t coun
size_t read = 0;
int status = 0;

if (count != 0 && count < sizeof(struct surface_dtx_event)) {
if (count != 0 && count < sizeof(struct surface_dtx_event))
return -EINVAL;
}

if (!ddev->active) {
if (!ddev->active)
return -ENODEV;
}

// check availability
if (client->buffer_head == client->buffer_tail){
if (file->f_flags & O_NONBLOCK) {
if (client->buffer_head == client->buffer_tail) {
if (file->f_flags & O_NONBLOCK)
return -EAGAIN;
}

status = wait_event_interruptible(ddev->waitq,
client->buffer_head != client->buffer_tail ||
!ddev->active);
if (status) {
if (status)
return status;
}

if (!ddev->active) {
if (!ddev->active)
return -ENODEV;
}
}

// copy events one by one
while (read + sizeof(struct surface_dtx_event) <= count) {
spin_lock_irq(&client->buffer_lock);

if(client->buffer_head == client->buffer_tail) {
if (client->buffer_head == client->buffer_tail) {
spin_unlock_irq(&client->buffer_lock);
break;
}
Expand All @@ -251,9 +244,8 @@ static ssize_t surface_dtx_read(struct file *file, char __user *buf, size_t coun
spin_unlock_irq(&client->buffer_lock);

// copy to userspace
if(copy_to_user(buf, &event, sizeof(struct surface_dtx_event))) {
if (copy_to_user(buf, &event, sizeof(struct surface_dtx_event)))
return -EFAULT;
}

read += sizeof(struct surface_dtx_event);
}
Expand All @@ -268,15 +260,13 @@ static __poll_t surface_dtx_poll(struct file *file, struct poll_table_struct *pt

poll_wait(file, &client->ddev->waitq, pt);

if (client->ddev->active) {
if (client->ddev->active)
mask = EPOLLOUT | EPOLLWRNORM;
} else {
else
mask = EPOLLHUP | EPOLLERR;
}

if (client->buffer_head != client->buffer_tail) {
if (client->buffer_head != client->buffer_tail)
mask |= EPOLLIN | EPOLLRDNORM;
}

return mask;
}
Expand All @@ -295,9 +285,8 @@ static long surface_dtx_ioctl(struct file *file, unsigned int cmd, unsigned long
int status;

status = mutex_lock_interruptible(&ddev->mutex);
if (status) {
if (status)
return status;
}

if (!ddev->active) {
mutex_unlock(&ddev->mutex);
Expand Down Expand Up @@ -391,9 +380,8 @@ static void surface_dtx_update_opmpde(struct surface_dtx_dev *ddev)

// get operation mode
opmode = surface_sam_query_opmpde();
if (opmode < 0) {
if (opmode < 0)
printk(DTX_ERR "EC request failed with error %d\n", opmode);
}

// send DTX event
event.type = 0x11;
Expand All @@ -405,7 +393,7 @@ static void surface_dtx_update_opmpde(struct surface_dtx_dev *ddev)

// send SW_TABLET_MODE event
spin_lock(&ddev->input_lock);
input_report_switch(ddev->input_dev, SW_TABLET_MODE, opmode == 0x00);
input_report_switch(ddev->input_dev, SW_TABLET_MODE, opmode != DTX_OPMODE_LAPTOP);
input_sync(ddev->input_dev);
spin_unlock(&ddev->input_lock);
}
Expand Down Expand Up @@ -455,14 +443,12 @@ static int surface_dtx_events_setup(struct surface_dtx_dev *ddev)
int status;

status = surface_sam_ssh_set_event_handler(SAM_EVENT_DTX_RQID, surface_dtx_evt_dtx, ddev);
if (status) {
if (status)
goto err_handler;
}

status = surface_sam_ssh_enable_event_source(SAM_EVENT_DTX_TC, 0x01, SAM_EVENT_DTX_RQID);
if (status) {
if (status)
goto err_source;
}

return 0;

Expand All @@ -485,9 +471,8 @@ static struct input_dev *surface_dtx_register_inputdev(struct platform_device *p
int status;

input_dev = input_allocate_device();
if (!input_dev) {
if (!input_dev)
return ERR_PTR(-ENOMEM);
}

input_dev->name = DTX_INPUT_NAME;
input_dev->dev.parent = &pdev->dev;
Expand All @@ -503,7 +488,7 @@ static struct input_dev *surface_dtx_register_inputdev(struct platform_device *p
return ERR_PTR(status);
}

input_report_switch(input_dev, SW_TABLET_MODE, status == 0x00);
input_report_switch(input_dev, SW_TABLET_MODE, status != DTX_OPMODE_LAPTOP);

status = input_register_device(input_dev);
if (status) {
Expand All @@ -523,14 +508,12 @@ static int surface_sam_dtx_probe(struct platform_device *pdev)

// link to ec
status = surface_sam_ssh_consumer_register(&pdev->dev);
if (status) {
if (status)
return status == -ENXIO ? -EPROBE_DEFER : status;
}

input_dev = surface_dtx_register_inputdev(pdev);
if (IS_ERR(input_dev)) {
if (IS_ERR(input_dev))
return PTR_ERR(input_dev);
}

// initialize device
mutex_lock(&ddev->mutex);
Expand All @@ -547,15 +530,13 @@ static int surface_sam_dtx_probe(struct platform_device *pdev)
mutex_unlock(&ddev->mutex);

status = misc_register(&ddev->mdev);
if (status) {
if (status)
goto err_register;
}

// enable events
status = surface_dtx_events_setup(ddev);
if (status) {
if (status)
goto err_events_setup;
}

return 0;

Expand Down
Loading

0 comments on commit fa33900

Please sign in to comment.