aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorOleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>2018-06-12 18:04:43 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2018-06-12 18:11:00 -0400
commit3ef8a2eeb6dcd1fa61ec8ae107976e655f50e412 (patch)
treec817ef4ca6f1d22035159a86df5ca26b7b64d9f4 /drivers/input/misc
parentce6f7d087e2b037f47349c1c36ac97678d02e394 (diff)
Input: xen-kbdfront - allow better run-time configuration
It is now only possible to control if multi-touch virtual device is created or not (via the corresponding XenStore entries), but keyboard and pointer devices are always created. In some cases this is not desirable. For example, if virtual keyboard device is exposed to Android then the latter won't automatically show on-screen keyboard as it expects that a physical keyboard device can be used for typing. Utilize keyboard and pointer device XenStore feature fields to configure which virtual devices are created: - set "feature-disable-keyboard" to 1 if no keyboard device needs to be created - set "feature-disable-pointer" to 1 if no pointer device needs to be created Keep old behavior by default. Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> Suggested-by: Andrii Chepurnyi <andrii_chepurnyi@epam.com> Tested-by: Andrii Chepurnyi <andrii_chepurnyi@epam.com> Reviewed-by: Juergen Gross <jgross@suse.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/misc')
-rw-r--r--drivers/input/misc/xen-kbdfront.c177
1 files changed, 106 insertions, 71 deletions
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
index 92d739649022..594f72e39639 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -63,6 +63,9 @@ static void xenkbd_disconnect_backend(struct xenkbd_info *);
63static void xenkbd_handle_motion_event(struct xenkbd_info *info, 63static void xenkbd_handle_motion_event(struct xenkbd_info *info,
64 struct xenkbd_motion *motion) 64 struct xenkbd_motion *motion)
65{ 65{
66 if (unlikely(!info->ptr))
67 return;
68
66 input_report_rel(info->ptr, REL_X, motion->rel_x); 69 input_report_rel(info->ptr, REL_X, motion->rel_x);
67 input_report_rel(info->ptr, REL_Y, motion->rel_y); 70 input_report_rel(info->ptr, REL_Y, motion->rel_y);
68 if (motion->rel_z) 71 if (motion->rel_z)
@@ -73,6 +76,9 @@ static void xenkbd_handle_motion_event(struct xenkbd_info *info,
73static void xenkbd_handle_position_event(struct xenkbd_info *info, 76static void xenkbd_handle_position_event(struct xenkbd_info *info,
74 struct xenkbd_position *pos) 77 struct xenkbd_position *pos)
75{ 78{
79 if (unlikely(!info->ptr))
80 return;
81
76 input_report_abs(info->ptr, ABS_X, pos->abs_x); 82 input_report_abs(info->ptr, ABS_X, pos->abs_x);
77 input_report_abs(info->ptr, ABS_Y, pos->abs_y); 83 input_report_abs(info->ptr, ABS_Y, pos->abs_y);
78 if (pos->rel_z) 84 if (pos->rel_z)
@@ -97,6 +103,9 @@ static void xenkbd_handle_key_event(struct xenkbd_info *info,
97 return; 103 return;
98 } 104 }
99 105
106 if (unlikely(!dev))
107 return;
108
100 input_event(dev, EV_KEY, key->keycode, value); 109 input_event(dev, EV_KEY, key->keycode, value);
101 input_sync(dev); 110 input_sync(dev);
102} 111}
@@ -192,7 +201,7 @@ static int xenkbd_probe(struct xenbus_device *dev,
192 const struct xenbus_device_id *id) 201 const struct xenbus_device_id *id)
193{ 202{
194 int ret, i; 203 int ret, i;
195 unsigned int abs, touch; 204 bool with_mtouch, with_kbd, with_ptr;
196 struct xenkbd_info *info; 205 struct xenkbd_info *info;
197 struct input_dev *kbd, *ptr, *mtouch; 206 struct input_dev *kbd, *ptr, *mtouch;
198 207
@@ -211,93 +220,114 @@ static int xenkbd_probe(struct xenbus_device *dev,
211 if (!info->page) 220 if (!info->page)
212 goto error_nomem; 221 goto error_nomem;
213 222
214 /* Set input abs params to match backend screen res */ 223 /*
215 abs = xenbus_read_unsigned(dev->otherend, 224 * The below are reverse logic, e.g. if the feature is set, then
216 XENKBD_FIELD_FEAT_ABS_POINTER, 0); 225 * do not expose the corresponding virtual device.
217 ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend, 226 */
218 XENKBD_FIELD_WIDTH, 227 with_kbd = !xenbus_read_unsigned(dev->otherend,
219 ptr_size[KPARAM_X]); 228 XENKBD_FIELD_FEAT_DSBL_KEYBRD, 0);
220 ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend, 229
221 XENKBD_FIELD_HEIGHT, 230 with_ptr = !xenbus_read_unsigned(dev->otherend,
222 ptr_size[KPARAM_Y]); 231 XENKBD_FIELD_FEAT_DSBL_POINTER, 0);
223 if (abs) {
224 ret = xenbus_write(XBT_NIL, dev->nodename,
225 XENKBD_FIELD_REQ_ABS_POINTER, "1");
226 if (ret) {
227 pr_warn("xenkbd: can't request abs-pointer\n");
228 abs = 0;
229 }
230 }
231 232
232 touch = xenbus_read_unsigned(dev->otherend, 233 /* Direct logic: if set, then create multi-touch device. */
233 XENKBD_FIELD_FEAT_MTOUCH, 0); 234 with_mtouch = xenbus_read_unsigned(dev->otherend,
234 if (touch) { 235 XENKBD_FIELD_FEAT_MTOUCH, 0);
236 if (with_mtouch) {
235 ret = xenbus_write(XBT_NIL, dev->nodename, 237 ret = xenbus_write(XBT_NIL, dev->nodename,
236 XENKBD_FIELD_REQ_MTOUCH, "1"); 238 XENKBD_FIELD_REQ_MTOUCH, "1");
237 if (ret) { 239 if (ret) {
238 pr_warn("xenkbd: can't request multi-touch"); 240 pr_warn("xenkbd: can't request multi-touch");
239 touch = 0; 241 with_mtouch = 0;
240 } 242 }
241 } 243 }
242 244
243 /* keyboard */ 245 /* keyboard */
244 kbd = input_allocate_device(); 246 if (with_kbd) {
245 if (!kbd) 247 kbd = input_allocate_device();
246 goto error_nomem; 248 if (!kbd)
247 kbd->name = "Xen Virtual Keyboard"; 249 goto error_nomem;
248 kbd->phys = info->phys; 250 kbd->name = "Xen Virtual Keyboard";
249 kbd->id.bustype = BUS_PCI; 251 kbd->phys = info->phys;
250 kbd->id.vendor = 0x5853; 252 kbd->id.bustype = BUS_PCI;
251 kbd->id.product = 0xffff; 253 kbd->id.vendor = 0x5853;
252 254 kbd->id.product = 0xffff;
253 __set_bit(EV_KEY, kbd->evbit); 255
254 for (i = KEY_ESC; i < KEY_UNKNOWN; i++) 256 __set_bit(EV_KEY, kbd->evbit);
255 __set_bit(i, kbd->keybit); 257 for (i = KEY_ESC; i < KEY_UNKNOWN; i++)
256 for (i = KEY_OK; i < KEY_MAX; i++) 258 __set_bit(i, kbd->keybit);
257 __set_bit(i, kbd->keybit); 259 for (i = KEY_OK; i < KEY_MAX; i++)
258 260 __set_bit(i, kbd->keybit);
259 ret = input_register_device(kbd); 261
260 if (ret) { 262 ret = input_register_device(kbd);
261 input_free_device(kbd); 263 if (ret) {
262 xenbus_dev_fatal(dev, ret, "input_register_device(kbd)"); 264 input_free_device(kbd);
263 goto error; 265 xenbus_dev_fatal(dev, ret,
266 "input_register_device(kbd)");
267 goto error;
268 }
269 info->kbd = kbd;
264 } 270 }
265 info->kbd = kbd;
266 271
267 /* pointing device */ 272 /* pointing device */
268 ptr = input_allocate_device(); 273 if (with_ptr) {
269 if (!ptr) 274 unsigned int abs;
270 goto error_nomem; 275
271 ptr->name = "Xen Virtual Pointer"; 276 /* Set input abs params to match backend screen res */
272 ptr->phys = info->phys; 277 abs = xenbus_read_unsigned(dev->otherend,
273 ptr->id.bustype = BUS_PCI; 278 XENKBD_FIELD_FEAT_ABS_POINTER, 0);
274 ptr->id.vendor = 0x5853; 279 ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend,
275 ptr->id.product = 0xfffe; 280 XENKBD_FIELD_WIDTH,
276 281 ptr_size[KPARAM_X]);
277 if (abs) { 282 ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend,
278 __set_bit(EV_ABS, ptr->evbit); 283 XENKBD_FIELD_HEIGHT,
279 input_set_abs_params(ptr, ABS_X, 0, ptr_size[KPARAM_X], 0, 0); 284 ptr_size[KPARAM_Y]);
280 input_set_abs_params(ptr, ABS_Y, 0, ptr_size[KPARAM_Y], 0, 0); 285 if (abs) {
281 } else { 286 ret = xenbus_write(XBT_NIL, dev->nodename,
282 input_set_capability(ptr, EV_REL, REL_X); 287 XENKBD_FIELD_REQ_ABS_POINTER, "1");
283 input_set_capability(ptr, EV_REL, REL_Y); 288 if (ret) {
284 } 289 pr_warn("xenkbd: can't request abs-pointer\n");
285 input_set_capability(ptr, EV_REL, REL_WHEEL); 290 abs = 0;
291 }
292 }
286 293
287 __set_bit(EV_KEY, ptr->evbit); 294 ptr = input_allocate_device();
288 for (i = BTN_LEFT; i <= BTN_TASK; i++) 295 if (!ptr)
289 __set_bit(i, ptr->keybit); 296 goto error_nomem;
297 ptr->name = "Xen Virtual Pointer";
298 ptr->phys = info->phys;
299 ptr->id.bustype = BUS_PCI;
300 ptr->id.vendor = 0x5853;
301 ptr->id.product = 0xfffe;
302
303 if (abs) {
304 __set_bit(EV_ABS, ptr->evbit);
305 input_set_abs_params(ptr, ABS_X, 0,
306 ptr_size[KPARAM_X], 0, 0);
307 input_set_abs_params(ptr, ABS_Y, 0,
308 ptr_size[KPARAM_Y], 0, 0);
309 } else {
310 input_set_capability(ptr, EV_REL, REL_X);
311 input_set_capability(ptr, EV_REL, REL_Y);
312 }
313 input_set_capability(ptr, EV_REL, REL_WHEEL);
290 314
291 ret = input_register_device(ptr); 315 __set_bit(EV_KEY, ptr->evbit);
292 if (ret) { 316 for (i = BTN_LEFT; i <= BTN_TASK; i++)
293 input_free_device(ptr); 317 __set_bit(i, ptr->keybit);
294 xenbus_dev_fatal(dev, ret, "input_register_device(ptr)"); 318
295 goto error; 319 ret = input_register_device(ptr);
320 if (ret) {
321 input_free_device(ptr);
322 xenbus_dev_fatal(dev, ret,
323 "input_register_device(ptr)");
324 goto error;
325 }
326 info->ptr = ptr;
296 } 327 }
297 info->ptr = ptr;
298 328
299 /* multi-touch device */ 329 /* multi-touch device */
300 if (touch) { 330 if (with_mtouch) {
301 int num_cont, width, height; 331 int num_cont, width, height;
302 332
303 mtouch = input_allocate_device(); 333 mtouch = input_allocate_device();
@@ -346,6 +376,11 @@ static int xenkbd_probe(struct xenbus_device *dev,
346 info->mtouch = mtouch; 376 info->mtouch = mtouch;
347 } 377 }
348 378
379 if (!(with_kbd || with_ptr || with_mtouch)) {
380 ret = -ENXIO;
381 goto error;
382 }
383
349 ret = xenkbd_connect_backend(dev, info); 384 ret = xenkbd_connect_backend(dev, info);
350 if (ret < 0) 385 if (ret < 0)
351 goto error; 386 goto error;