Blame view

drivers/misc/ibmasm/remote.c 9.95 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  /*
   * IBM ASM Service Processor Device Driver
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that 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, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   *
   * Copyright (C) IBM Corporation, 2004
   *
96de0e252   Jan Engelhardt   Convert files to ...
20
   * Authors: Max Asböck <amax@us.ibm.com>
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
21
   *          Vernon Mauery <vernux@us.ibm.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
25
   *
   */
  
  /* Remote mouse and keyboard event handling functions */
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
26
  #include <linux/pci.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
  #include "ibmasm.h"
  #include "remote.h"
894549569   Dmitry Torokhov   IBMASM: miscellan...
29
30
  #define MOUSE_X_MAX	1600
  #define MOUSE_Y_MAX	1200
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31

894549569   Dmitry Torokhov   IBMASM: miscellan...
32
  static const unsigned short xlate_high[XLATE_SIZE] = {
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  	[KEY_SYM_ENTER & 0xff] = KEY_ENTER,
  	[KEY_SYM_KPSLASH & 0xff] = KEY_KPSLASH,
  	[KEY_SYM_KPSTAR & 0xff] = KEY_KPASTERISK,
  	[KEY_SYM_KPMINUS & 0xff] = KEY_KPMINUS,
  	[KEY_SYM_KPDOT & 0xff] = KEY_KPDOT,
  	[KEY_SYM_KPPLUS & 0xff] = KEY_KPPLUS,
  	[KEY_SYM_KP0 & 0xff] = KEY_KP0,
  	[KEY_SYM_KP1 & 0xff] = KEY_KP1,
  	[KEY_SYM_KP2 & 0xff] = KEY_KP2, [KEY_SYM_KPDOWN & 0xff] = KEY_KP2,
  	[KEY_SYM_KP3 & 0xff] = KEY_KP3,
  	[KEY_SYM_KP4 & 0xff] = KEY_KP4, [KEY_SYM_KPLEFT & 0xff] = KEY_KP4,
  	[KEY_SYM_KP5 & 0xff] = KEY_KP5,
  	[KEY_SYM_KP6 & 0xff] = KEY_KP6, [KEY_SYM_KPRIGHT & 0xff] = KEY_KP6,
  	[KEY_SYM_KP7 & 0xff] = KEY_KP7,
  	[KEY_SYM_KP8 & 0xff] = KEY_KP8, [KEY_SYM_KPUP & 0xff] = KEY_KP8,
  	[KEY_SYM_KP9 & 0xff] = KEY_KP9,
  	[KEY_SYM_BK_SPC & 0xff] = KEY_BACKSPACE,
  	[KEY_SYM_TAB & 0xff] = KEY_TAB,
  	[KEY_SYM_CTRL & 0xff] = KEY_LEFTCTRL,
  	[KEY_SYM_ALT & 0xff] = KEY_LEFTALT,
  	[KEY_SYM_INSERT & 0xff] = KEY_INSERT,
  	[KEY_SYM_DELETE & 0xff] = KEY_DELETE,
  	[KEY_SYM_SHIFT & 0xff] = KEY_LEFTSHIFT,
  	[KEY_SYM_UARROW & 0xff] = KEY_UP,
  	[KEY_SYM_DARROW & 0xff] = KEY_DOWN,
  	[KEY_SYM_LARROW & 0xff] = KEY_LEFT,
  	[KEY_SYM_RARROW & 0xff] = KEY_RIGHT,
  	[KEY_SYM_ESCAPE & 0xff] = KEY_ESC,
          [KEY_SYM_PAGEUP & 0xff] = KEY_PAGEUP,
          [KEY_SYM_PAGEDOWN & 0xff] = KEY_PAGEDOWN,
          [KEY_SYM_HOME & 0xff] = KEY_HOME,
          [KEY_SYM_END & 0xff] = KEY_END,
  	[KEY_SYM_F1 & 0xff] = KEY_F1,
  	[KEY_SYM_F2 & 0xff] = KEY_F2,
  	[KEY_SYM_F3 & 0xff] = KEY_F3,
  	[KEY_SYM_F4 & 0xff] = KEY_F4,
  	[KEY_SYM_F5 & 0xff] = KEY_F5,
  	[KEY_SYM_F6 & 0xff] = KEY_F6,
  	[KEY_SYM_F7 & 0xff] = KEY_F7,
  	[KEY_SYM_F8 & 0xff] = KEY_F8,
  	[KEY_SYM_F9 & 0xff] = KEY_F9,
  	[KEY_SYM_F10 & 0xff] = KEY_F10,
  	[KEY_SYM_F11 & 0xff] = KEY_F11,
  	[KEY_SYM_F12 & 0xff] = KEY_F12,
  	[KEY_SYM_CAP_LOCK & 0xff] = KEY_CAPSLOCK,
  	[KEY_SYM_NUM_LOCK & 0xff] = KEY_NUMLOCK,
  	[KEY_SYM_SCR_LOCK & 0xff] = KEY_SCROLLLOCK,
  };
894549569   Dmitry Torokhov   IBMASM: miscellan...
81
82
  
  static const unsigned short xlate[XLATE_SIZE] = {
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  	[NO_KEYCODE] = KEY_RESERVED,
  	[KEY_SYM_SPACE] = KEY_SPACE,
  	[KEY_SYM_TILDE] = KEY_GRAVE,        [KEY_SYM_BKTIC] = KEY_GRAVE,
  	[KEY_SYM_ONE] = KEY_1,              [KEY_SYM_BANG] = KEY_1,
  	[KEY_SYM_TWO] = KEY_2,              [KEY_SYM_AT] = KEY_2,
  	[KEY_SYM_THREE] = KEY_3,            [KEY_SYM_POUND] = KEY_3,
  	[KEY_SYM_FOUR] = KEY_4,             [KEY_SYM_DOLLAR] = KEY_4,
  	[KEY_SYM_FIVE] = KEY_5,             [KEY_SYM_PERCENT] = KEY_5,
  	[KEY_SYM_SIX] = KEY_6,              [KEY_SYM_CARAT] = KEY_6,
  	[KEY_SYM_SEVEN] = KEY_7,            [KEY_SYM_AMPER] = KEY_7,
  	[KEY_SYM_EIGHT] = KEY_8,            [KEY_SYM_STAR] = KEY_8,
  	[KEY_SYM_NINE] = KEY_9,             [KEY_SYM_LPAREN] = KEY_9,
  	[KEY_SYM_ZERO] = KEY_0,             [KEY_SYM_RPAREN] = KEY_0,
  	[KEY_SYM_MINUS] = KEY_MINUS,        [KEY_SYM_USCORE] = KEY_MINUS,
  	[KEY_SYM_EQUAL] = KEY_EQUAL,        [KEY_SYM_PLUS] = KEY_EQUAL,
  	[KEY_SYM_LBRKT] = KEY_LEFTBRACE,    [KEY_SYM_LCURLY] = KEY_LEFTBRACE,
  	[KEY_SYM_RBRKT] = KEY_RIGHTBRACE,   [KEY_SYM_RCURLY] = KEY_RIGHTBRACE,
  	[KEY_SYM_SLASH] = KEY_BACKSLASH,    [KEY_SYM_PIPE] = KEY_BACKSLASH,
  	[KEY_SYM_TIC] = KEY_APOSTROPHE,     [KEY_SYM_QUOTE] = KEY_APOSTROPHE,
  	[KEY_SYM_SEMIC] = KEY_SEMICOLON,    [KEY_SYM_COLON] = KEY_SEMICOLON,
  	[KEY_SYM_COMMA] = KEY_COMMA,        [KEY_SYM_LT] = KEY_COMMA,
  	[KEY_SYM_PERIOD] = KEY_DOT,         [KEY_SYM_GT] = KEY_DOT,
  	[KEY_SYM_BSLASH] = KEY_SLASH,       [KEY_SYM_QMARK] = KEY_SLASH,
  	[KEY_SYM_A] = KEY_A,                [KEY_SYM_a] = KEY_A,
  	[KEY_SYM_B] = KEY_B,                [KEY_SYM_b] = KEY_B,
  	[KEY_SYM_C] = KEY_C,                [KEY_SYM_c] = KEY_C,
  	[KEY_SYM_D] = KEY_D,                [KEY_SYM_d] = KEY_D,
  	[KEY_SYM_E] = KEY_E,                [KEY_SYM_e] = KEY_E,
  	[KEY_SYM_F] = KEY_F,                [KEY_SYM_f] = KEY_F,
  	[KEY_SYM_G] = KEY_G,                [KEY_SYM_g] = KEY_G,
  	[KEY_SYM_H] = KEY_H,                [KEY_SYM_h] = KEY_H,
  	[KEY_SYM_I] = KEY_I,                [KEY_SYM_i] = KEY_I,
  	[KEY_SYM_J] = KEY_J,                [KEY_SYM_j] = KEY_J,
  	[KEY_SYM_K] = KEY_K,                [KEY_SYM_k] = KEY_K,
  	[KEY_SYM_L] = KEY_L,                [KEY_SYM_l] = KEY_L,
  	[KEY_SYM_M] = KEY_M,                [KEY_SYM_m] = KEY_M,
  	[KEY_SYM_N] = KEY_N,                [KEY_SYM_n] = KEY_N,
  	[KEY_SYM_O] = KEY_O,                [KEY_SYM_o] = KEY_O,
  	[KEY_SYM_P] = KEY_P,                [KEY_SYM_p] = KEY_P,
  	[KEY_SYM_Q] = KEY_Q,                [KEY_SYM_q] = KEY_Q,
  	[KEY_SYM_R] = KEY_R,                [KEY_SYM_r] = KEY_R,
  	[KEY_SYM_S] = KEY_S,                [KEY_SYM_s] = KEY_S,
  	[KEY_SYM_T] = KEY_T,                [KEY_SYM_t] = KEY_T,
  	[KEY_SYM_U] = KEY_U,                [KEY_SYM_u] = KEY_U,
  	[KEY_SYM_V] = KEY_V,                [KEY_SYM_v] = KEY_V,
  	[KEY_SYM_W] = KEY_W,                [KEY_SYM_w] = KEY_W,
  	[KEY_SYM_X] = KEY_X,                [KEY_SYM_x] = KEY_X,
  	[KEY_SYM_Y] = KEY_Y,                [KEY_SYM_y] = KEY_Y,
  	[KEY_SYM_Z] = KEY_Z,                [KEY_SYM_z] = KEY_Z,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133

278d72ae8   Max Asbock   [PATCH] ibmasm dr...
134
  static void print_input(struct remote_input *input)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
  {
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
136
137
138
139
140
  	if (input->type == INPUT_TYPE_MOUSE) {
  		unsigned char buttons = input->mouse_buttons;
  		dbg("remote mouse movement: (x,y)=(%d,%d)%s%s%s%s
  ",
  			input->data.mouse.x, input->data.mouse.y,
894549569   Dmitry Torokhov   IBMASM: miscellan...
141
142
143
144
  			(buttons) ? " -- buttons:" : "",
  			(buttons & REMOTE_BUTTON_LEFT) ? "left " : "",
  			(buttons & REMOTE_BUTTON_MIDDLE) ? "middle " : "",
  			(buttons & REMOTE_BUTTON_RIGHT) ? "right" : ""
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
145
146
147
148
149
150
151
152
153
154
155
  		      );
  	} else {
  		dbg("remote keypress (code, flag, down):"
  			   "%d (0x%x) [0x%x] [0x%x]
  ",
  				input->data.keyboard.key_code,
  				input->data.keyboard.key_code,
  				input->data.keyboard.key_flag,
  				input->data.keyboard.key_down
  		      );
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
  }
7d12e780e   David Howells   IRQ: Maintain reg...
157
  static void send_mouse_event(struct input_dev *dev, struct remote_input *input)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  {
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
159
  	unsigned char buttons = input->mouse_buttons;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160

278d72ae8   Max Asbock   [PATCH] ibmasm dr...
161
162
163
164
165
166
  	input_report_abs(dev, ABS_X, input->data.mouse.x);
  	input_report_abs(dev, ABS_Y, input->data.mouse.y);
  	input_report_key(dev, BTN_LEFT, buttons & REMOTE_BUTTON_LEFT);
  	input_report_key(dev, BTN_MIDDLE, buttons & REMOTE_BUTTON_MIDDLE);
  	input_report_key(dev, BTN_RIGHT, buttons & REMOTE_BUTTON_RIGHT);
  	input_sync(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168

7d12e780e   David Howells   IRQ: Maintain reg...
169
  static void send_keyboard_event(struct input_dev *dev,
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
170
  		struct remote_input *input)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
  {
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
172
173
  	unsigned int key;
  	unsigned short code = input->data.keyboard.key_code;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174

278d72ae8   Max Asbock   [PATCH] ibmasm dr...
175
176
177
178
  	if (code & 0xff00)
  		key = xlate_high[code & 0xff];
  	else
  		key = xlate[code];
894549569   Dmitry Torokhov   IBMASM: miscellan...
179
  	input_report_key(dev, key, input->data.keyboard.key_down);
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
180
  	input_sync(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  }
7d12e780e   David Howells   IRQ: Maintain reg...
182
  void ibmasm_handle_mouse_interrupt(struct service_processor *sp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
  {
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
184
185
186
  	unsigned long reader;
  	unsigned long writer;
  	struct remote_input input;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187

278d72ae8   Max Asbock   [PATCH] ibmasm dr...
188
189
  	reader = get_queue_reader(sp);
  	writer = get_queue_writer(sp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190

278d72ae8   Max Asbock   [PATCH] ibmasm dr...
191
192
193
  	while (reader != writer) {
  		memcpy_fromio(&input, get_queue_entry(sp, reader),
  				sizeof(struct remote_input));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194

278d72ae8   Max Asbock   [PATCH] ibmasm dr...
195
196
  		print_input(&input);
  		if (input.type == INPUT_TYPE_MOUSE) {
7d12e780e   David Howells   IRQ: Maintain reg...
197
  			send_mouse_event(sp->remote.mouse_dev, &input);
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
198
  		} else if (input.type == INPUT_TYPE_KEYBOARD) {
7d12e780e   David Howells   IRQ: Maintain reg...
199
  			send_keyboard_event(sp->remote.keybd_dev, &input);
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
200
201
  		} else
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202

278d72ae8   Max Asbock   [PATCH] ibmasm dr...
203
204
205
  		reader = advance_queue_reader(sp, reader);
  		writer = get_queue_writer(sp);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  }
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
207
  int ibmasm_init_remote_input_dev(struct service_processor *sp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
  {
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
209
  	/* set up the mouse input device */
736ce4329   Vernon Mauery   Input: ibmasm - c...
210
  	struct input_dev *mouse_dev, *keybd_dev;
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
211
  	struct pci_dev *pdev = to_pci_dev(sp->dev);
736ce4329   Vernon Mauery   Input: ibmasm - c...
212
  	int error = -ENOMEM;
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
213
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214

736ce4329   Vernon Mauery   Input: ibmasm - c...
215
216
  	sp->remote.mouse_dev = mouse_dev = input_allocate_device();
  	sp->remote.keybd_dev = keybd_dev = input_allocate_device();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217

736ce4329   Vernon Mauery   Input: ibmasm - c...
218
219
  	if (!mouse_dev || !keybd_dev)
  		goto err_free_devices;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220

736ce4329   Vernon Mauery   Input: ibmasm - c...
221
222
223
224
  	mouse_dev->id.bustype = BUS_PCI;
  	mouse_dev->id.vendor = pdev->vendor;
  	mouse_dev->id.product = pdev->device;
  	mouse_dev->id.version = 1;
894549569   Dmitry Torokhov   IBMASM: miscellan...
225
  	mouse_dev->dev.parent = sp->dev;
7b19ada2e   Jiri Slaby   get rid of input ...
226
227
228
  	mouse_dev->evbit[0]  = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  	mouse_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
  		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
736ce4329   Vernon Mauery   Input: ibmasm - c...
229
  	set_bit(BTN_TOUCH, mouse_dev->keybit);
894549569   Dmitry Torokhov   IBMASM: miscellan...
230
231
232
  	mouse_dev->name = "ibmasm RSA I remote mouse";
  	input_set_abs_params(mouse_dev, ABS_X, 0, MOUSE_X_MAX, 0, 0);
  	input_set_abs_params(mouse_dev, ABS_Y, 0, MOUSE_Y_MAX, 0, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233

894549569   Dmitry Torokhov   IBMASM: miscellan...
234
  	keybd_dev->id.bustype = BUS_PCI;
736ce4329   Vernon Mauery   Input: ibmasm - c...
235
236
  	keybd_dev->id.vendor = pdev->vendor;
  	keybd_dev->id.product = pdev->device;
894549569   Dmitry Torokhov   IBMASM: miscellan...
237
238
  	keybd_dev->id.version = 2;
  	keybd_dev->dev.parent = sp->dev;
7b19ada2e   Jiri Slaby   get rid of input ...
239
  	keybd_dev->evbit[0]  = BIT_MASK(EV_KEY);
894549569   Dmitry Torokhov   IBMASM: miscellan...
240
  	keybd_dev->name = "ibmasm RSA I remote keyboard";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241

736ce4329   Vernon Mauery   Input: ibmasm - c...
242
  	for (i = 0; i < XLATE_SIZE; i++) {
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
243
  		if (xlate_high[i])
736ce4329   Vernon Mauery   Input: ibmasm - c...
244
  			set_bit(xlate_high[i], keybd_dev->keybit);
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
245
  		if (xlate[i])
736ce4329   Vernon Mauery   Input: ibmasm - c...
246
  			set_bit(xlate[i], keybd_dev->keybit);
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
247
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248

736ce4329   Vernon Mauery   Input: ibmasm - c...
249
250
251
252
253
254
255
  	error = input_register_device(mouse_dev);
  	if (error)
  		goto err_free_devices;
  
  	error = input_register_device(keybd_dev);
  	if (error)
  		goto err_unregister_mouse_dev;
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
256
  	enable_mouse_interrupts(sp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257

278d72ae8   Max Asbock   [PATCH] ibmasm dr...
258
259
  	printk(KERN_INFO "ibmasm remote responding to events on RSA card %d
  ", sp->number);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260

278d72ae8   Max Asbock   [PATCH] ibmasm dr...
261
  	return 0;
736ce4329   Vernon Mauery   Input: ibmasm - c...
262
263
264
  
   err_unregister_mouse_dev:
  	input_unregister_device(mouse_dev);
5fc4e6e19   Dmitry Torokhov   Input: ibmasm - f...
265
  	mouse_dev = NULL; /* so we don't try to free it again below */
736ce4329   Vernon Mauery   Input: ibmasm - c...
266
267
268
269
270
   err_free_devices:
  	input_free_device(mouse_dev);
  	input_free_device(keybd_dev);
  
  	return error;
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
271
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272

278d72ae8   Max Asbock   [PATCH] ibmasm dr...
273
274
275
  void ibmasm_free_remote_input_dev(struct service_processor *sp)
  {
  	disable_mouse_interrupts(sp);
736ce4329   Vernon Mauery   Input: ibmasm - c...
276
277
  	input_unregister_device(sp->remote.mouse_dev);
  	input_unregister_device(sp->remote.keybd_dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
  }
278d72ae8   Max Asbock   [PATCH] ibmasm dr...
279