.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Surface2.0/SUR40/PixelSense input driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
14 | 15 | * |
---|
15 | 16 | * and from the v4l2-pci-skeleton driver, |
---|
16 | 17 | * Copyright (c) Copyright 2014 Cisco Systems, Inc. |
---|
17 | | - * |
---|
18 | | - * This program is free software; you can redistribute it and/or |
---|
19 | | - * modify it under the terms of the GNU General Public License as |
---|
20 | | - * published by the Free Software Foundation; either version 2 of |
---|
21 | | - * the License, or (at your option) any later version. |
---|
22 | 18 | */ |
---|
23 | 19 | |
---|
24 | 20 | #include <linux/kernel.h> |
---|
.. | .. |
---|
31 | 27 | #include <linux/uaccess.h> |
---|
32 | 28 | #include <linux/usb.h> |
---|
33 | 29 | #include <linux/printk.h> |
---|
34 | | -#include <linux/input-polldev.h> |
---|
| 30 | +#include <linux/input.h> |
---|
35 | 31 | #include <linux/input/mt.h> |
---|
36 | 32 | #include <linux/usb/input.h> |
---|
37 | 33 | #include <linux/videodev2.h> |
---|
.. | .. |
---|
190 | 186 | .width = SENSOR_RES_X / 2, |
---|
191 | 187 | .height = SENSOR_RES_Y / 2, |
---|
192 | 188 | .field = V4L2_FIELD_NONE, |
---|
193 | | - .colorspace = V4L2_COLORSPACE_SRGB, |
---|
| 189 | + .colorspace = V4L2_COLORSPACE_RAW, |
---|
194 | 190 | .bytesperline = SENSOR_RES_X / 2, |
---|
195 | 191 | .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2), |
---|
196 | 192 | }, |
---|
.. | .. |
---|
199 | 195 | .width = SENSOR_RES_X / 2, |
---|
200 | 196 | .height = SENSOR_RES_Y / 2, |
---|
201 | 197 | .field = V4L2_FIELD_NONE, |
---|
202 | | - .colorspace = V4L2_COLORSPACE_SRGB, |
---|
| 198 | + .colorspace = V4L2_COLORSPACE_RAW, |
---|
203 | 199 | .bytesperline = SENSOR_RES_X / 2, |
---|
204 | 200 | .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2), |
---|
205 | 201 | } |
---|
.. | .. |
---|
210 | 206 | |
---|
211 | 207 | struct usb_device *usbdev; |
---|
212 | 208 | struct device *dev; |
---|
213 | | - struct input_polled_dev *input; |
---|
| 209 | + struct input_dev *input; |
---|
214 | 210 | |
---|
215 | 211 | struct v4l2_device v4l2; |
---|
216 | 212 | struct video_device vdev; |
---|
.. | .. |
---|
374 | 370 | goto error; |
---|
375 | 371 | |
---|
376 | 372 | result = sur40_command(dev, SUR40_GET_VERSION, 0x03, buffer, 12); |
---|
| 373 | + if (result < 0) |
---|
| 374 | + goto error; |
---|
| 375 | + |
---|
| 376 | + result = 0; |
---|
377 | 377 | |
---|
378 | 378 | /* |
---|
379 | 379 | * Discard the result buffer - no known data inside except |
---|
.. | .. |
---|
385 | 385 | } |
---|
386 | 386 | |
---|
387 | 387 | /* |
---|
388 | | - * Callback routines from input_polled_dev |
---|
| 388 | + * Callback routines from input_dev |
---|
389 | 389 | */ |
---|
390 | 390 | |
---|
391 | 391 | /* Enable the device, polling will now start. */ |
---|
392 | | -static void sur40_open(struct input_polled_dev *polldev) |
---|
| 392 | +static int sur40_open(struct input_dev *input) |
---|
393 | 393 | { |
---|
394 | | - struct sur40_state *sur40 = polldev->private; |
---|
| 394 | + struct sur40_state *sur40 = input_get_drvdata(input); |
---|
395 | 395 | |
---|
396 | 396 | dev_dbg(sur40->dev, "open\n"); |
---|
397 | | - sur40_init(sur40); |
---|
| 397 | + return sur40_init(sur40); |
---|
398 | 398 | } |
---|
399 | 399 | |
---|
400 | 400 | /* Disable device, polling has stopped. */ |
---|
401 | | -static void sur40_close(struct input_polled_dev *polldev) |
---|
| 401 | +static void sur40_close(struct input_dev *input) |
---|
402 | 402 | { |
---|
403 | | - struct sur40_state *sur40 = polldev->private; |
---|
| 403 | + struct sur40_state *sur40 = input_get_drvdata(input); |
---|
404 | 404 | |
---|
405 | 405 | dev_dbg(sur40->dev, "close\n"); |
---|
406 | 406 | /* |
---|
.. | .. |
---|
452 | 452 | } |
---|
453 | 453 | |
---|
454 | 454 | /* core function: poll for new input data */ |
---|
455 | | -static void sur40_poll(struct input_polled_dev *polldev) |
---|
| 455 | +static void sur40_poll(struct input_dev *input) |
---|
456 | 456 | { |
---|
457 | | - struct sur40_state *sur40 = polldev->private; |
---|
458 | | - struct input_dev *input = polldev->input; |
---|
| 457 | + struct sur40_state *sur40 = input_get_drvdata(input); |
---|
459 | 458 | int result, bulk_read, need_blobs, packet_blobs, i; |
---|
460 | | - u32 uninitialized_var(packet_id); |
---|
461 | | - |
---|
462 | 459 | struct sur40_header *header = &sur40->bulk_in_buffer->header; |
---|
463 | 460 | struct sur40_blob *inblob = &sur40->bulk_in_buffer->blobs[0]; |
---|
464 | 461 | |
---|
.. | .. |
---|
492 | 489 | if (need_blobs == -1) { |
---|
493 | 490 | need_blobs = le16_to_cpu(header->count); |
---|
494 | 491 | dev_dbg(sur40->dev, "need %d blobs\n", need_blobs); |
---|
495 | | - packet_id = le32_to_cpu(header->packet_id); |
---|
| 492 | + /* packet_id = le32_to_cpu(header->packet_id); */ |
---|
496 | 493 | } |
---|
497 | 494 | |
---|
498 | 495 | /* |
---|
.. | .. |
---|
617 | 614 | } |
---|
618 | 615 | |
---|
619 | 616 | /* Initialize input device parameters. */ |
---|
620 | | -static void sur40_input_setup(struct input_dev *input_dev) |
---|
| 617 | +static int sur40_input_setup_events(struct input_dev *input_dev) |
---|
621 | 618 | { |
---|
622 | | - __set_bit(EV_KEY, input_dev->evbit); |
---|
623 | | - __set_bit(EV_ABS, input_dev->evbit); |
---|
| 619 | + int error; |
---|
624 | 620 | |
---|
625 | 621 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
---|
626 | 622 | 0, SENSOR_RES_X, 0, 0); |
---|
.. | .. |
---|
641 | 637 | |
---|
642 | 638 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); |
---|
643 | 639 | |
---|
644 | | - input_mt_init_slots(input_dev, MAX_CONTACTS, |
---|
645 | | - INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); |
---|
| 640 | + error = input_mt_init_slots(input_dev, MAX_CONTACTS, |
---|
| 641 | + INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); |
---|
| 642 | + if (error) { |
---|
| 643 | + dev_err(input_dev->dev.parent, "failed to set up slots\n"); |
---|
| 644 | + return error; |
---|
| 645 | + } |
---|
| 646 | + |
---|
| 647 | + return 0; |
---|
646 | 648 | } |
---|
647 | 649 | |
---|
648 | 650 | /* Check candidate USB interface. */ |
---|
.. | .. |
---|
653 | 655 | struct sur40_state *sur40; |
---|
654 | 656 | struct usb_host_interface *iface_desc; |
---|
655 | 657 | struct usb_endpoint_descriptor *endpoint; |
---|
656 | | - struct input_polled_dev *poll_dev; |
---|
| 658 | + struct input_dev *input; |
---|
657 | 659 | int error; |
---|
658 | 660 | |
---|
659 | 661 | /* Check if we really have the right interface. */ |
---|
.. | .. |
---|
674 | 676 | if (!sur40) |
---|
675 | 677 | return -ENOMEM; |
---|
676 | 678 | |
---|
677 | | - poll_dev = input_allocate_polled_device(); |
---|
678 | | - if (!poll_dev) { |
---|
| 679 | + input = input_allocate_device(); |
---|
| 680 | + if (!input) { |
---|
679 | 681 | error = -ENOMEM; |
---|
680 | 682 | goto err_free_dev; |
---|
681 | 683 | } |
---|
.. | .. |
---|
685 | 687 | spin_lock_init(&sur40->qlock); |
---|
686 | 688 | mutex_init(&sur40->lock); |
---|
687 | 689 | |
---|
688 | | - /* Set up polled input device control structure */ |
---|
689 | | - poll_dev->private = sur40; |
---|
690 | | - poll_dev->poll_interval = POLL_INTERVAL; |
---|
691 | | - poll_dev->open = sur40_open; |
---|
692 | | - poll_dev->poll = sur40_poll; |
---|
693 | | - poll_dev->close = sur40_close; |
---|
694 | | - |
---|
695 | 690 | /* Set up regular input device structure */ |
---|
696 | | - sur40_input_setup(poll_dev->input); |
---|
697 | | - |
---|
698 | | - poll_dev->input->name = DRIVER_LONG; |
---|
699 | | - usb_to_input_id(usbdev, &poll_dev->input->id); |
---|
| 691 | + input->name = DRIVER_LONG; |
---|
| 692 | + usb_to_input_id(usbdev, &input->id); |
---|
700 | 693 | usb_make_path(usbdev, sur40->phys, sizeof(sur40->phys)); |
---|
701 | 694 | strlcat(sur40->phys, "/input0", sizeof(sur40->phys)); |
---|
702 | | - poll_dev->input->phys = sur40->phys; |
---|
703 | | - poll_dev->input->dev.parent = &interface->dev; |
---|
| 695 | + input->phys = sur40->phys; |
---|
| 696 | + input->dev.parent = &interface->dev; |
---|
| 697 | + |
---|
| 698 | + input->open = sur40_open; |
---|
| 699 | + input->close = sur40_close; |
---|
| 700 | + |
---|
| 701 | + error = sur40_input_setup_events(input); |
---|
| 702 | + if (error) |
---|
| 703 | + goto err_free_input; |
---|
| 704 | + |
---|
| 705 | + input_set_drvdata(input, sur40); |
---|
| 706 | + error = input_setup_polling(input, sur40_poll); |
---|
| 707 | + if (error) { |
---|
| 708 | + dev_err(&interface->dev, "failed to set up polling"); |
---|
| 709 | + goto err_free_input; |
---|
| 710 | + } |
---|
| 711 | + |
---|
| 712 | + input_set_poll_interval(input, POLL_INTERVAL); |
---|
704 | 713 | |
---|
705 | 714 | sur40->usbdev = usbdev; |
---|
706 | 715 | sur40->dev = &interface->dev; |
---|
707 | | - sur40->input = poll_dev; |
---|
| 716 | + sur40->input = input; |
---|
708 | 717 | |
---|
709 | 718 | /* use the bulk-in endpoint tested above */ |
---|
710 | 719 | sur40->bulk_in_size = usb_endpoint_maxp(endpoint); |
---|
.. | .. |
---|
713 | 722 | if (!sur40->bulk_in_buffer) { |
---|
714 | 723 | dev_err(&interface->dev, "Unable to allocate input buffer."); |
---|
715 | 724 | error = -ENOMEM; |
---|
716 | | - goto err_free_polldev; |
---|
| 725 | + goto err_free_input; |
---|
717 | 726 | } |
---|
718 | 727 | |
---|
719 | 728 | /* register the polled input device */ |
---|
720 | | - error = input_register_polled_device(poll_dev); |
---|
| 729 | + error = input_register_device(input); |
---|
721 | 730 | if (error) { |
---|
722 | 731 | dev_err(&interface->dev, |
---|
723 | 732 | "Unable to register polled input device."); |
---|
.. | .. |
---|
801 | 810 | v4l2_device_unregister(&sur40->v4l2); |
---|
802 | 811 | err_free_buffer: |
---|
803 | 812 | kfree(sur40->bulk_in_buffer); |
---|
804 | | -err_free_polldev: |
---|
805 | | - input_free_polled_device(sur40->input); |
---|
| 813 | +err_free_input: |
---|
| 814 | + input_free_device(input); |
---|
806 | 815 | err_free_dev: |
---|
807 | 816 | kfree(sur40); |
---|
808 | 817 | |
---|
.. | .. |
---|
818 | 827 | video_unregister_device(&sur40->vdev); |
---|
819 | 828 | v4l2_device_unregister(&sur40->v4l2); |
---|
820 | 829 | |
---|
821 | | - input_unregister_polled_device(sur40->input); |
---|
822 | | - input_free_polled_device(sur40->input); |
---|
| 830 | + input_unregister_device(sur40->input); |
---|
823 | 831 | kfree(sur40->bulk_in_buffer); |
---|
824 | 832 | kfree(sur40); |
---|
825 | 833 | |
---|
.. | .. |
---|
934 | 942 | strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver)); |
---|
935 | 943 | strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card)); |
---|
936 | 944 | usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info)); |
---|
937 | | - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TOUCH | |
---|
938 | | - V4L2_CAP_READWRITE | |
---|
939 | | - V4L2_CAP_STREAMING; |
---|
940 | | - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
---|
941 | 945 | return 0; |
---|
942 | 946 | } |
---|
943 | 947 | |
---|
.. | .. |
---|
1167 | 1171 | .fops = &sur40_video_fops, |
---|
1168 | 1172 | .ioctl_ops = &sur40_video_ioctl_ops, |
---|
1169 | 1173 | .release = video_device_release_empty, |
---|
| 1174 | + .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TOUCH | |
---|
| 1175 | + V4L2_CAP_READWRITE | V4L2_CAP_STREAMING, |
---|
1170 | 1176 | }; |
---|
1171 | 1177 | |
---|
1172 | 1178 | /* USB-specific object needed to register this driver with the USB subsystem. */ |
---|