#include <linux/types.h>
#include <linux/input.h>
#include <linux/acpi.h>
+#include <linux/platform_device.h>
#include <acpi/button.h>
#define SURFACE_PRO3_BUTTON_HID "MSHW0028"
static void surface_button_notify(acpi_handle handle, u32 event, void *data)
{
- struct acpi_device *device = data;
- struct surface_button *button = acpi_driver_data(device);
+ struct device *dev = data;
+ struct surface_button *button = dev_get_drvdata(dev);
struct input_dev *input;
int key_code = KEY_RESERVED;
bool pressed = false;
key_code = KEY_VOLUMEDOWN;
break;
case SURFACE_BUTTON_NOTIFY_TABLET_MODE:
- dev_warn_once(&device->dev, "Tablet mode is not supported\n");
+ dev_warn_once(dev, "Tablet mode is not supported\n");
break;
default:
- dev_info_ratelimited(&device->dev,
- "Unsupported event [0x%x]\n", event);
+ dev_info_ratelimited(dev, "Unsupported event [0x%x]\n", event);
break;
}
input = button->input;
if (key_code == KEY_RESERVED)
return;
if (pressed)
- pm_wakeup_dev_event(&device->dev, 0, button->suspended);
+ pm_wakeup_dev_event(dev, 0, button->suspended);
if (button->suspended)
return;
input_report_key(input, key_code, pressed?1:0);
#ifdef CONFIG_PM_SLEEP
static int surface_button_suspend(struct device *dev)
{
- struct acpi_device *device = to_acpi_device(dev);
- struct surface_button *button = acpi_driver_data(device);
+ struct surface_button *button = dev_get_drvdata(dev);
button->suspended = true;
return 0;
static int surface_button_resume(struct device *dev)
{
- struct acpi_device *device = to_acpi_device(dev);
- struct surface_button *button = acpi_driver_data(device);
+ struct surface_button *button = dev_get_drvdata(dev);
button->suspended = false;
return 0;
* Returns true if the driver should bind to this device, i.e. the device is
* either MSWH0028 (Pro 3) or MSHW0040 on a Pro 4 or Book 1.
*/
-static bool surface_button_check_MSHW0040(struct acpi_device *dev)
+static bool surface_button_check_MSHW0040(struct device *dev, acpi_handle handle)
{
- acpi_handle handle = dev->handle;
union acpi_object *result;
u64 oem_platform_rev = 0; // valid revisions are nonzero
ACPI_FREE(result);
}
- dev_dbg(&dev->dev, "OEM Platform Revision %llu\n", oem_platform_rev);
+ dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev);
return oem_platform_rev == 0;
}
-static int surface_button_add(struct acpi_device *device)
+static int surface_button_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
struct surface_button *button;
struct input_dev *input;
const char *hid = acpi_device_hid(device);
strlen(SURFACE_BUTTON_OBJ_NAME)))
return -ENODEV;
- if (!surface_button_check_MSHW0040(device))
+ if (!surface_button_check_MSHW0040(&pdev->dev, device->handle))
return -ENODEV;
button = kzalloc_obj(struct surface_button);
if (!button)
return -ENOMEM;
- device->driver_data = button;
+ platform_set_drvdata(pdev, button);
button->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
input->name = acpi_device_name(device);
input->phys = button->phys;
input->id.bustype = BUS_HOST;
- input->dev.parent = &device->dev;
+ input->dev.parent = &pdev->dev;
input_set_capability(input, EV_KEY, KEY_POWER);
input_set_capability(input, EV_KEY, KEY_LEFTMETA);
input_set_capability(input, EV_KEY, KEY_VOLUMEUP);
if (error)
goto err_free_input;
- device_init_wakeup(&device->dev, true);
+ device_init_wakeup(&pdev->dev, true);
error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
- surface_button_notify, device);
+ surface_button_notify, &pdev->dev);
if (error) {
- device_init_wakeup(&device->dev, false);
+ device_init_wakeup(&pdev->dev, false);
input_unregister_device(input);
goto err_free_button;
}
- dev_info(&device->dev, "%s [%s]\n", acpi_device_name(device),
+ dev_info(&pdev->dev, "%s [%s]\n", acpi_device_name(device),
acpi_device_bid(device));
return 0;
return error;
}
-static void surface_button_remove(struct acpi_device *device)
+static void surface_button_remove(struct platform_device *pdev)
{
- struct surface_button *button = acpi_driver_data(device);
+ struct surface_button *button = platform_get_drvdata(pdev);
- acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
- surface_button_notify);
- device_init_wakeup(&device->dev, false);
+ acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
+ ACPI_DEVICE_NOTIFY, surface_button_notify);
+ device_init_wakeup(&pdev->dev, false);
input_unregister_device(button->input);
kfree(button);
}
static SIMPLE_DEV_PM_OPS(surface_button_pm,
surface_button_suspend, surface_button_resume);
-static struct acpi_driver surface_button_driver = {
- .name = "surface_pro3_button",
- .class = "SurfacePro3",
- .ids = surface_button_device_ids,
- .ops = {
- .add = surface_button_add,
- .remove = surface_button_remove,
+static struct platform_driver surface_button_driver = {
+ .probe = surface_button_probe,
+ .remove = surface_button_remove,
+ .driver = {
+ .name = "surface_pro3_button",
+ .acpi_match_table = surface_button_device_ids,
+ .pm = &surface_button_pm,
},
- .drv.pm = &surface_button_pm,
};
-module_acpi_driver(surface_button_driver);
+module_platform_driver(surface_button_driver);