aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Herring <rob.herring@calxeda.com>2011-12-22 15:45:19 -0600
committerJohn Rigby <john.rigby@linaro.org>2012-06-25 15:02:28 -0600
commit62ea718987be2d1aff874eca357394ffbd0098c2 (patch)
treeabe169f1083a734920befef9e63ced8931647c33
parent39236f38675856bf1068ca9f8dedc5c90ebd860e (diff)
UBUNTU: SAUCE: input: add a key driver for highbank
BugLink: http://bugs.launchpad.net/bugs/1000831 Add a keyboard driver to handle power and sleep keys from the management controller. These are generated via ipc messages. Signed-off-by: Rob Herring <rob.herring@calxeda.com> Signed-off-by: Ike Panhc <ike.pan@canonical.com> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
-rw-r--r--arch/arm/boot/dts/highbank.dts4
-rw-r--r--drivers/input/keyboard/Kconfig11
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/highbank_keys.c141
4 files changed, 157 insertions, 0 deletions
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index 83e72294aef..e735731ae39 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -124,6 +124,10 @@
interrupts = <0 7 4>;
};
+ ipc-keys {
+ compatible = "calxeda,hb-keys";
+ };
+
gpioe: gpio@fff30000 {
#gpio-cells = <2>;
compatible = "arm,pl061", "arm,primecell";
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index c0e11ecc646..c99bf9065f7 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -204,6 +204,17 @@ config KEYBOARD_GPIO_POLLED
To compile this driver as a module, choose M here: the
module will be called gpio_keys_polled.
+config KEYBOARD_HIGHBANK
+ tristate "Calxeda Highbank Virtual Keys"
+ depends on ARCH_HIGHBANK
+ default y
+ help
+ This driver implements support for virtual power keys on Calxeda
+ Highbank systems.
+
+ To compile this driver as a module, choose M here: the
+ module will be called highbank_keys.
+
config KEYBOARD_TCA6416
tristate "TCA6416/TCA6408A Keypad Support"
depends on I2C
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index b03b02456a8..5dc046906f3 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o
obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o
+obj-$(CONFIG_KEYBOARD_HIGHBANK) += highbank_keys.o
obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o
obj-$(CONFIG_KEYBOARD_TCA8418) += tca8418_keypad.o
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
diff --git a/drivers/input/keyboard/highbank_keys.c b/drivers/input/keyboard/highbank_keys.c
new file mode 100644
index 00000000000..a84ecf37175
--- /dev/null
+++ b/drivers/input/keyboard/highbank_keys.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2011 Calxeda, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+
+#include <mach/pl320-ipc.h>
+
+struct hb_keys_drvdata {
+ struct input_dev *input;
+ struct notifier_block nb;
+};
+
+int hb_keys_notifier(struct notifier_block *nb, unsigned long event, void *data)
+{
+ struct hb_keys_drvdata *ddata = container_of(nb, struct hb_keys_drvdata, nb);
+ struct input_dev *input = ddata->input;
+ u32 *d = data;
+ u32 key = d[0];
+
+ if (event != 0x1000 /*HB_IPC_KEY*/)
+ return 0;
+
+ input_event(input, EV_KEY, key, 1);
+ input_event(input, EV_KEY, key, 0);
+ input_sync(input);
+ return 0;
+}
+
+static int hb_keys_open(struct input_dev *input)
+{
+ struct hb_keys_drvdata *ddata = input_get_drvdata(input);
+ return pl320_ipc_register_notifier(&ddata->nb);
+}
+
+static void hb_keys_close(struct input_dev *input)
+{
+ struct hb_keys_drvdata *ddata = input_get_drvdata(input);
+ pl320_ipc_unregister_notifier(&ddata->nb);
+}
+
+static int __devinit hb_keys_probe(struct platform_device *pdev)
+{
+ struct hb_keys_drvdata *ddata;
+ struct device *dev = &pdev->dev;
+ struct input_dev *input;
+ int error;
+
+ ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ input = input_allocate_device();
+ if (!input) {
+ dev_err(dev, "failed to allocate state\n");
+ error = -ENOMEM;
+ goto fail1;
+ }
+
+ platform_set_drvdata(pdev, ddata);
+ input_set_drvdata(input, ddata);
+
+ ddata->input = input;
+ ddata->nb.notifier_call = hb_keys_notifier;
+
+ input->name = pdev->name;
+ input->phys = "highbank/input0";
+ input->dev.parent = &pdev->dev;
+ input->open = hb_keys_open;
+ input->close = hb_keys_close;
+
+ input->id.bustype = BUS_HOST;
+ input->id.vendor = 0x0001;
+ input->id.product = 0x0001;
+ input->id.version = 0x0100;
+
+ input_set_capability(input, EV_KEY, KEY_POWER);
+ input_set_capability(input, EV_KEY, KEY_SLEEP);
+
+ error = input_register_device(input);
+ if (error) {
+ dev_err(dev, "Unable to register input device, error: %d\n",
+ error);
+ goto fail2;
+ }
+
+ return 0;
+
+ fail2:
+ input_free_device(input);
+ fail1:
+ kfree(ddata);
+ return error;
+}
+
+static int __devexit hb_keys_remove(struct platform_device *pdev)
+{
+ struct hb_keys_drvdata *ddata = platform_get_drvdata(pdev);
+ input_unregister_device(ddata->input);
+ kfree(ddata);
+ return 0;
+}
+
+static struct of_device_id hb_keys_of_match[] = {
+ { .compatible = "calxeda,hb-keys", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, hb_keys_of_match);
+
+static struct platform_driver hb_keys_driver = {
+ .probe = hb_keys_probe,
+ .remove = __devexit_p(hb_keys_remove),
+ .driver = {
+ .name = "hb-keys",
+ .of_match_table = hb_keys_of_match,
+ }
+};
+
+module_platform_driver(hb_keys_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Calxeda, Inc.");
+MODULE_DESCRIPTION("Keys driver for Calxeda Highbank");