linux/drivers/platform/x86/hp-wireless.c
<<
>>
Prefs
   1/*
   2 *  hp-wireless button for Windows 8
   3 *
   4 *  Copyright (C) 2014 Alex Hung <alex.hung@canonical.com>
   5 *
   6 *  This program is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License as published by
   8 *  the Free Software Foundation; either version 2 of the License, or
   9 *  (at your option) any later version.
  10 *
  11 *  This program is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *  GNU General Public License for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License along
  17 *  with this program; if not, write to the Free Software Foundation, Inc.,
  18 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19 */
  20
  21#include <linux/kernel.h>
  22#include <linux/module.h>
  23#include <linux/init.h>
  24#include <linux/input.h>
  25#include <linux/platform_device.h>
  26#include <linux/acpi.h>
  27#include <acpi/acpi_bus.h>
  28
  29MODULE_LICENSE("GPL");
  30MODULE_AUTHOR("Alex Hung");
  31MODULE_ALIAS("acpi*:HPQ6001:*");
  32
  33static struct input_dev *hpwl_input_dev;
  34
  35static const struct acpi_device_id hpwl_ids[] = {
  36        {"HPQ6001", 0},
  37        {"", 0},
  38};
  39
  40static int hp_wireless_input_setup(void)
  41{
  42        int err;
  43
  44        hpwl_input_dev = input_allocate_device();
  45        if (!hpwl_input_dev)
  46                return -ENOMEM;
  47
  48        hpwl_input_dev->name = "HP Wireless hotkeys";
  49        hpwl_input_dev->phys = "hpq6001/input0";
  50        hpwl_input_dev->id.bustype = BUS_HOST;
  51        hpwl_input_dev->evbit[0] = BIT(EV_KEY);
  52        set_bit(KEY_RFKILL, hpwl_input_dev->keybit);
  53
  54        err = input_register_device(hpwl_input_dev);
  55        if (err)
  56                goto err_free_dev;
  57
  58        return 0;
  59
  60err_free_dev:
  61        input_free_device(hpwl_input_dev);
  62        return err;
  63}
  64
  65static void hp_wireless_input_destroy(void)
  66{
  67        input_unregister_device(hpwl_input_dev);
  68}
  69
  70static void hpwl_notify(struct acpi_device *acpi_dev, u32 event)
  71{
  72        if (event != 0x80) {
  73                pr_info("Received unknown event (0x%x)\n", event);
  74                return;
  75        }
  76
  77        input_report_key(hpwl_input_dev, KEY_RFKILL, 1);
  78        input_sync(hpwl_input_dev);
  79        input_report_key(hpwl_input_dev, KEY_RFKILL, 0);
  80        input_sync(hpwl_input_dev);
  81}
  82
  83static int hpwl_add(struct acpi_device *device)
  84{
  85        int err;
  86
  87        err = hp_wireless_input_setup();
  88        if (err)
  89                pr_err("Failed to setup hp wireless hotkeys\n");
  90
  91        return err;
  92}
  93
  94static int hpwl_remove(struct acpi_device *device)
  95{
  96        hp_wireless_input_destroy();
  97        return 0;
  98}
  99
 100static struct acpi_driver hpwl_driver = {
 101        .name   = "hp-wireless",
 102        .owner  = THIS_MODULE,
 103        .ids    = hpwl_ids,
 104        .ops    = {
 105                .add    = hpwl_add,
 106                .remove = hpwl_remove,
 107                .notify = hpwl_notify,
 108        },
 109};
 110
 111static int __init hpwl_init(void)
 112{
 113        int err;
 114
 115        pr_info("Initializing HPQ6001 module\n");
 116        err = acpi_bus_register_driver(&hpwl_driver);
 117        if (err) {
 118                pr_err("Unable to register HP wireless control driver.\n");
 119                goto error_acpi_register;
 120        }
 121
 122        return 0;
 123
 124error_acpi_register:
 125        return err;
 126}
 127
 128static void __exit hpwl_exit(void)
 129{
 130        pr_info("Exiting HPQ6001 module\n");
 131        acpi_bus_unregister_driver(&hpwl_driver);
 132}
 133
 134module_init(hpwl_init);
 135module_exit(hpwl_exit);
 136
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.