2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
6 * h3600 atmel micro companion support, key subdevice
7 * based on previous kernel 2.4 version
8 * Author : Alessandro Gardich <gremlin@gremlin.it>
9 * Author : Linus Walleij <linus.walleij@linaro.org>
12 #include <linux/module.h>
13 #include <linux/init.h>
15 #include <linux/interrupt.h>
16 #include <linux/sched.h>
18 #include <linux/sysctl.h>
19 #include <linux/proc_fs.h>
20 #include <linux/delay.h>
21 #include <linux/device.h>
22 #include <linux/input.h>
23 #include <linux/platform_device.h>
24 #include <linux/mfd/ipaq-micro.h>
26 struct ipaq_micro_keys
{
27 struct ipaq_micro
*micro
;
28 struct input_dev
*input
;
32 static const u16 micro_keycodes
[] = {
33 KEY_RECORD
, /* 1: Record button */
34 KEY_CALENDAR
, /* 2: Calendar */
35 KEY_ADDRESSBOOK
, /* 3: Contacts (looks like Outlook) */
36 KEY_MAIL
, /* 4: Envelope (Q on older iPAQs) */
37 KEY_HOMEPAGE
, /* 5: Start (looks like swoopy arrow) */
39 KEY_RIGHT
, /* 7: Right */
40 KEY_LEFT
, /* 8: Left */
41 KEY_DOWN
, /* 9: Down */
44 static void micro_key_receive(void *data
, int len
, unsigned char *msg
)
46 struct ipaq_micro_keys
*keys
= data
;
52 if (key
< ARRAY_SIZE(micro_keycodes
)) {
53 input_report_key(keys
->input
, keys
->codes
[key
], down
);
54 input_sync(keys
->input
);
58 static void micro_key_start(struct ipaq_micro_keys
*keys
)
60 spin_lock(&keys
->micro
->lock
);
61 keys
->micro
->key
= micro_key_receive
;
62 keys
->micro
->key_data
= keys
;
63 spin_unlock(&keys
->micro
->lock
);
66 static void micro_key_stop(struct ipaq_micro_keys
*keys
)
68 spin_lock(&keys
->micro
->lock
);
69 keys
->micro
->key
= NULL
;
70 keys
->micro
->key_data
= NULL
;
71 spin_unlock(&keys
->micro
->lock
);
74 static int micro_key_open(struct input_dev
*input
)
76 struct ipaq_micro_keys
*keys
= input_get_drvdata(input
);
78 micro_key_start(keys
);
83 static void micro_key_close(struct input_dev
*input
)
85 struct ipaq_micro_keys
*keys
= input_get_drvdata(input
);
90 static int micro_key_probe(struct platform_device
*pdev
)
92 struct ipaq_micro_keys
*keys
;
96 keys
= devm_kzalloc(&pdev
->dev
, sizeof(*keys
), GFP_KERNEL
);
100 keys
->micro
= dev_get_drvdata(pdev
->dev
.parent
);
102 keys
->input
= devm_input_allocate_device(&pdev
->dev
);
106 keys
->input
->keycodesize
= sizeof(micro_keycodes
[0]);
107 keys
->input
->keycodemax
= ARRAY_SIZE(micro_keycodes
);
108 keys
->codes
= devm_kmemdup(&pdev
->dev
, micro_keycodes
,
109 keys
->input
->keycodesize
* keys
->input
->keycodemax
,
111 keys
->input
->keycode
= keys
->codes
;
113 __set_bit(EV_KEY
, keys
->input
->evbit
);
114 for (i
= 0; i
< ARRAY_SIZE(micro_keycodes
); i
++)
115 __set_bit(micro_keycodes
[i
], keys
->input
->keybit
);
117 keys
->input
->name
= "h3600 micro keys";
118 keys
->input
->open
= micro_key_open
;
119 keys
->input
->close
= micro_key_close
;
120 input_set_drvdata(keys
->input
, keys
);
122 error
= input_register_device(keys
->input
);
126 platform_set_drvdata(pdev
, keys
);
130 static int __maybe_unused
micro_key_suspend(struct device
*dev
)
132 struct ipaq_micro_keys
*keys
= dev_get_drvdata(dev
);
134 micro_key_stop(keys
);
139 static int __maybe_unused
micro_key_resume(struct device
*dev
)
141 struct ipaq_micro_keys
*keys
= dev_get_drvdata(dev
);
142 struct input_dev
*input
= keys
->input
;
144 mutex_lock(&input
->mutex
);
147 micro_key_start(keys
);
149 mutex_unlock(&input
->mutex
);
154 static SIMPLE_DEV_PM_OPS(micro_key_dev_pm_ops
,
155 micro_key_suspend
, micro_key_resume
);
157 static struct platform_driver micro_key_device_driver
= {
159 .name
= "ipaq-micro-keys",
160 .pm
= µ_key_dev_pm_ops
,
162 .probe
= micro_key_probe
,
164 module_platform_driver(micro_key_device_driver
);
166 MODULE_LICENSE("GPL");
167 MODULE_DESCRIPTION("driver for iPAQ Atmel micro keys");
168 MODULE_ALIAS("platform:ipaq-micro-keys");