aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-01 13:38:09 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-01 13:38:09 -0500
commit8724fdb53d27d7b59b60c8a399cc67f9abfabb33 (patch)
treeda2de791ed4845780376a5e6f844ab69957d565f /drivers/macintosh
parentbc535154137601400ffe44c2a7be047ca041fe06 (diff)
parent35858adbfca13678af99fb31618ef4428d6dedb0 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (62 commits) Input: atkbd - release previously reserved keycodes 248 - 254 Input: add KEY_WPS_BUTTON definition Input: ads7846 - add regulator support Input: winbond-cir - fix suspend/resume Input: gamecon - use pr_err() and friends Input: gamecon - constify some of the setup structures Input: gamecon - simplify pad type handling Input: gamecon - simplify coordinate calculation for PSX Input: gamecon - fix some formatting issues Input: gamecon - add rumble support for N64 pads Input: wacom - add device type to device name string Input: s3c24xx_ts - report touch only when stylus is down Input: s3c24xx_ts - re-enable IRQ on resume Input: wacom - constify product features data Input: wacom - use per-device instance of wacom_features Input: sh_keysc - enable building on SH-Mobile ARM Input: wacom - get features from driver info Input: rotary-encoder - set gpio direction for each requested gpio Input: sh_keysc - update the driver with mode 6 Input: sh_keysc - switch to using bitmaps ...
Diffstat (limited to 'drivers/macintosh')
-rw-r--r--drivers/macintosh/Kconfig7
-rw-r--r--drivers/macintosh/mac_hid.c266
2 files changed, 201 insertions, 72 deletions
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 3d906833948d..fd85bde283a0 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -171,8 +171,8 @@ config INPUT_ADBHID
171 If unsure, say Y. 171 If unsure, say Y.
172 172
173config MAC_EMUMOUSEBTN 173config MAC_EMUMOUSEBTN
174 bool "Support for mouse button 2+3 emulation" 174 tristate "Support for mouse button 2+3 emulation"
175 select INPUT 175 depends on SYSCTL && INPUT
176 help 176 help
177 This provides generic support for emulating the 2nd and 3rd mouse 177 This provides generic support for emulating the 2nd and 3rd mouse
178 button with keypresses. If you say Y here, the emulation is still 178 button with keypresses. If you say Y here, the emulation is still
@@ -184,6 +184,9 @@ config MAC_EMUMOUSEBTN
184 184
185 If you have an Apple machine with a 1-button mouse, say Y here. 185 If you have an Apple machine with a 1-button mouse, say Y here.
186 186
187 To compile this driver as a module, choose M here: the
188 module will be called mac_hid.
189
187config THERM_WINDTUNNEL 190config THERM_WINDTUNNEL
188 tristate "Support for thermal management on Windtunnel G4s" 191 tristate "Support for thermal management on Windtunnel G4s"
189 depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64 192 depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 7b4ef5bb556b..e943d2a29253 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -13,17 +13,197 @@
13#include <linux/sysctl.h> 13#include <linux/sysctl.h>
14#include <linux/input.h> 14#include <linux/input.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/kbd_kern.h>
17 16
17MODULE_LICENSE("GPL");
18 18
19static struct input_dev *emumousebtn;
20static int emumousebtn_input_register(void);
21static int mouse_emulate_buttons; 19static int mouse_emulate_buttons;
22static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */ 20static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */
23static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */ 21static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */
24static int mouse_last_keycode;
25 22
26#if defined(CONFIG_SYSCTL) 23static struct input_dev *mac_hid_emumouse_dev;
24
25static int mac_hid_create_emumouse(void)
26{
27 static struct lock_class_key mac_hid_emumouse_dev_event_class;
28 static struct lock_class_key mac_hid_emumouse_dev_mutex_class;
29 int err;
30
31 mac_hid_emumouse_dev = input_allocate_device();
32 if (!mac_hid_emumouse_dev)
33 return -ENOMEM;
34
35 lockdep_set_class(&mac_hid_emumouse_dev->event_lock,
36 &mac_hid_emumouse_dev_event_class);
37 lockdep_set_class(&mac_hid_emumouse_dev->mutex,
38 &mac_hid_emumouse_dev_mutex_class);
39
40 mac_hid_emumouse_dev->name = "Macintosh mouse button emulation";
41 mac_hid_emumouse_dev->id.bustype = BUS_ADB;
42 mac_hid_emumouse_dev->id.vendor = 0x0001;
43 mac_hid_emumouse_dev->id.product = 0x0001;
44 mac_hid_emumouse_dev->id.version = 0x0100;
45
46 mac_hid_emumouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
47 mac_hid_emumouse_dev->keybit[BIT_WORD(BTN_MOUSE)] =
48 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
49 mac_hid_emumouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
50
51 err = input_register_device(mac_hid_emumouse_dev);
52 if (err) {
53 input_free_device(mac_hid_emumouse_dev);
54 mac_hid_emumouse_dev = NULL;
55 return err;
56 }
57
58 return 0;
59}
60
61static void mac_hid_destroy_emumouse(void)
62{
63 input_unregister_device(mac_hid_emumouse_dev);
64 mac_hid_emumouse_dev = NULL;
65}
66
67static bool mac_hid_emumouse_filter(struct input_handle *handle,
68 unsigned int type, unsigned int code,
69 int value)
70{
71 unsigned int btn;
72
73 if (type != EV_KEY)
74 return false;
75
76 if (code == mouse_button2_keycode)
77 btn = BTN_MIDDLE;
78 else if (code == mouse_button3_keycode)
79 btn = BTN_RIGHT;
80 else
81 return false;
82
83 input_report_key(mac_hid_emumouse_dev, btn, value);
84 input_sync(mac_hid_emumouse_dev);
85
86 return true;
87}
88
89static int mac_hid_emumouse_connect(struct input_handler *handler,
90 struct input_dev *dev,
91 const struct input_device_id *id)
92{
93 struct input_handle *handle;
94 int error;
95
96 /* Don't bind to ourselves */
97 if (dev == mac_hid_emumouse_dev)
98 return -ENODEV;
99
100 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
101 if (!handle)
102 return -ENOMEM;
103
104 handle->dev = dev;
105 handle->handler = handler;
106 handle->name = "mac-button-emul";
107
108 error = input_register_handle(handle);
109 if (error) {
110 printk(KERN_ERR
111 "mac_hid: Failed to register button emulation handle, "
112 "error %d\n", error);
113 goto err_free;
114 }
115
116 error = input_open_device(handle);
117 if (error) {
118 printk(KERN_ERR
119 "mac_hid: Failed to open input device, error %d\n",
120 error);
121 goto err_unregister;
122 }
123
124 return 0;
125
126 err_unregister:
127 input_unregister_handle(handle);
128 err_free:
129 kfree(handle);
130 return error;
131}
132
133static void mac_hid_emumouse_disconnect(struct input_handle *handle)
134{
135 input_close_device(handle);
136 input_unregister_handle(handle);
137 kfree(handle);
138}
139
140static const struct input_device_id mac_hid_emumouse_ids[] = {
141 {
142 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
143 .evbit = { BIT_MASK(EV_KEY) },
144 },
145 { },
146};
147
148MODULE_DEVICE_TABLE(input, mac_hid_emumouse_ids);
149
150static struct input_handler mac_hid_emumouse_handler = {
151 .filter = mac_hid_emumouse_filter,
152 .connect = mac_hid_emumouse_connect,
153 .disconnect = mac_hid_emumouse_disconnect,
154 .name = "mac-button-emul",
155 .id_table = mac_hid_emumouse_ids,
156};
157
158static int mac_hid_start_emulation(void)
159{
160 int err;
161
162 err = mac_hid_create_emumouse();
163 if (err)
164 return err;
165
166 err = input_register_handler(&mac_hid_emumouse_handler);
167 if (err) {
168 mac_hid_destroy_emumouse();
169 return err;
170 }
171
172 return 0;
173}
174
175static void mac_hid_stop_emulation(void)
176{
177 input_unregister_handler(&mac_hid_emumouse_handler);
178 mac_hid_destroy_emumouse();
179}
180
181static int mac_hid_toggle_emumouse(ctl_table *table, int write,
182 void __user *buffer, size_t *lenp,
183 loff_t *ppos)
184{
185 int *valp = table->data;
186 int old_val = *valp;
187 int rc;
188
189 rc = proc_dointvec(table, write, buffer, lenp, ppos);
190
191 if (rc == 0 && write && *valp != old_val) {
192 if (*valp == 1)
193 rc = mac_hid_start_emulation();
194 else if (*valp == 0)
195 mac_hid_stop_emulation();
196 else
197 rc = -EINVAL;
198 }
199
200 /* Restore the old value in case of error */
201 if (rc)
202 *valp = old_val;
203
204 return rc;
205}
206
27/* file(s) in /proc/sys/dev/mac_hid */ 207/* file(s) in /proc/sys/dev/mac_hid */
28static ctl_table mac_hid_files[] = { 208static ctl_table mac_hid_files[] = {
29 { 209 {
@@ -31,7 +211,7 @@ static ctl_table mac_hid_files[] = {
31 .data = &mouse_emulate_buttons, 211 .data = &mouse_emulate_buttons,
32 .maxlen = sizeof(int), 212 .maxlen = sizeof(int),
33 .mode = 0644, 213 .mode = 0644,
34 .proc_handler = proc_dointvec, 214 .proc_handler = mac_hid_toggle_emumouse,
35 }, 215 },
36 { 216 {
37 .procname = "mouse_button2_keycode", 217 .procname = "mouse_button2_keycode",
@@ -74,75 +254,21 @@ static ctl_table mac_hid_root_dir[] = {
74 254
75static struct ctl_table_header *mac_hid_sysctl_header; 255static struct ctl_table_header *mac_hid_sysctl_header;
76 256
77#endif /* endif CONFIG_SYSCTL */ 257static int __init mac_hid_init(void)
78
79int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
80{
81 switch (caller) {
82 case 1:
83 /* Called from keyboard.c */
84 if (mouse_emulate_buttons
85 && (keycode == mouse_button2_keycode
86 || keycode == mouse_button3_keycode)) {
87 if (mouse_emulate_buttons == 1) {
88 input_report_key(emumousebtn,
89 keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
90 down);
91 input_sync(emumousebtn);
92 return 1;
93 }
94 mouse_last_keycode = down ? keycode : 0;
95 }
96 break;
97 }
98 return 0;
99}
100
101static struct lock_class_key emumousebtn_event_class;
102static struct lock_class_key emumousebtn_mutex_class;
103
104static int emumousebtn_input_register(void)
105{ 258{
106 int ret; 259 mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir);
107 260 if (!mac_hid_sysctl_header)
108 emumousebtn = input_allocate_device();
109 if (!emumousebtn)
110 return -ENOMEM; 261 return -ENOMEM;
111 262
112 lockdep_set_class(&emumousebtn->event_lock, &emumousebtn_event_class); 263 return 0;
113 lockdep_set_class(&emumousebtn->mutex, &emumousebtn_mutex_class);
114
115 emumousebtn->name = "Macintosh mouse button emulation";
116 emumousebtn->id.bustype = BUS_ADB;
117 emumousebtn->id.vendor = 0x0001;
118 emumousebtn->id.product = 0x0001;
119 emumousebtn->id.version = 0x0100;
120
121 emumousebtn->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
122 emumousebtn->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
123 BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
124 emumousebtn->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
125
126 ret = input_register_device(emumousebtn);
127 if (ret)
128 input_free_device(emumousebtn);
129
130 return ret;
131} 264}
265module_init(mac_hid_init);
132 266
133static int __init mac_hid_init(void) 267static void __exit mac_hid_exit(void)
134{ 268{
135 int err; 269 unregister_sysctl_table(mac_hid_sysctl_header);
136
137 err = emumousebtn_input_register();
138 if (err)
139 return err;
140
141#if defined(CONFIG_SYSCTL)
142 mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir);
143#endif /* CONFIG_SYSCTL */
144 270
145 return 0; 271 if (mouse_emulate_buttons)
272 mac_hid_stop_emulation();
146} 273}
147 274module_exit(mac_hid_exit);
148device_initcall(mac_hid_init);