cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

kbtab.c (5120B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2#include <linux/kernel.h>
      3#include <linux/slab.h>
      4#include <linux/module.h>
      5#include <linux/usb/input.h>
      6#include <asm/unaligned.h>
      7
      8/*
      9 * Pressure-threshold modules param code from Alex Perry <alex.perry@ieee.org>
     10 */
     11
     12MODULE_AUTHOR("Josh Myer <josh@joshisanerd.com>");
     13MODULE_DESCRIPTION("USB KB Gear JamStudio Tablet driver");
     14MODULE_LICENSE("GPL");
     15
     16#define USB_VENDOR_ID_KBGEAR	0x084e
     17
     18static int kb_pressure_click = 0x10;
     19module_param(kb_pressure_click, int, 0);
     20MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks");
     21
     22struct kbtab {
     23	unsigned char *data;
     24	dma_addr_t data_dma;
     25	struct input_dev *dev;
     26	struct usb_interface *intf;
     27	struct urb *irq;
     28	char phys[32];
     29};
     30
     31static void kbtab_irq(struct urb *urb)
     32{
     33	struct kbtab *kbtab = urb->context;
     34	unsigned char *data = kbtab->data;
     35	struct input_dev *dev = kbtab->dev;
     36	int pressure;
     37	int retval;
     38
     39	switch (urb->status) {
     40	case 0:
     41		/* success */
     42		break;
     43	case -ECONNRESET:
     44	case -ENOENT:
     45	case -ESHUTDOWN:
     46		/* this urb is terminated, clean up */
     47		dev_dbg(&kbtab->intf->dev,
     48			"%s - urb shutting down with status: %d\n",
     49			__func__, urb->status);
     50		return;
     51	default:
     52		dev_dbg(&kbtab->intf->dev,
     53			"%s - nonzero urb status received: %d\n",
     54			__func__, urb->status);
     55		goto exit;
     56	}
     57
     58
     59	input_report_key(dev, BTN_TOOL_PEN, 1);
     60
     61	input_report_abs(dev, ABS_X, get_unaligned_le16(&data[1]));
     62	input_report_abs(dev, ABS_Y, get_unaligned_le16(&data[3]));
     63
     64	/*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/
     65	input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
     66
     67	pressure = data[5];
     68	if (kb_pressure_click == -1)
     69		input_report_abs(dev, ABS_PRESSURE, pressure);
     70	else
     71		input_report_key(dev, BTN_LEFT, pressure > kb_pressure_click ? 1 : 0);
     72
     73	input_sync(dev);
     74
     75 exit:
     76	retval = usb_submit_urb(urb, GFP_ATOMIC);
     77	if (retval)
     78		dev_err(&kbtab->intf->dev,
     79			"%s - usb_submit_urb failed with result %d\n",
     80			__func__, retval);
     81}
     82
     83static const struct usb_device_id kbtab_ids[] = {
     84	{ USB_DEVICE(USB_VENDOR_ID_KBGEAR, 0x1001), .driver_info = 0 },
     85	{ }
     86};
     87
     88MODULE_DEVICE_TABLE(usb, kbtab_ids);
     89
     90static int kbtab_open(struct input_dev *dev)
     91{
     92	struct kbtab *kbtab = input_get_drvdata(dev);
     93	struct usb_device *udev = interface_to_usbdev(kbtab->intf);
     94
     95	kbtab->irq->dev = udev;
     96	if (usb_submit_urb(kbtab->irq, GFP_KERNEL))
     97		return -EIO;
     98
     99	return 0;
    100}
    101
    102static void kbtab_close(struct input_dev *dev)
    103{
    104	struct kbtab *kbtab = input_get_drvdata(dev);
    105
    106	usb_kill_urb(kbtab->irq);
    107}
    108
    109static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id)
    110{
    111	struct usb_device *dev = interface_to_usbdev(intf);
    112	struct usb_endpoint_descriptor *endpoint;
    113	struct kbtab *kbtab;
    114	struct input_dev *input_dev;
    115	int error = -ENOMEM;
    116
    117	if (intf->cur_altsetting->desc.bNumEndpoints < 1)
    118		return -ENODEV;
    119
    120	endpoint = &intf->cur_altsetting->endpoint[0].desc;
    121	if (!usb_endpoint_is_int_in(endpoint))
    122		return -ENODEV;
    123
    124	kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
    125	input_dev = input_allocate_device();
    126	if (!kbtab || !input_dev)
    127		goto fail1;
    128
    129	kbtab->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &kbtab->data_dma);
    130	if (!kbtab->data)
    131		goto fail1;
    132
    133	kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
    134	if (!kbtab->irq)
    135		goto fail2;
    136
    137	kbtab->intf = intf;
    138	kbtab->dev = input_dev;
    139
    140	usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
    141	strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys));
    142
    143	input_dev->name = "KB Gear Tablet";
    144	input_dev->phys = kbtab->phys;
    145	usb_to_input_id(dev, &input_dev->id);
    146	input_dev->dev.parent = &intf->dev;
    147
    148	input_set_drvdata(input_dev, kbtab);
    149
    150	input_dev->open = kbtab_open;
    151	input_dev->close = kbtab_close;
    152
    153	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
    154	input_dev->keybit[BIT_WORD(BTN_LEFT)] |=
    155		BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
    156	input_dev->keybit[BIT_WORD(BTN_DIGI)] |=
    157		BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_TOUCH);
    158	input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
    159	input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0);
    160	input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
    161
    162	usb_fill_int_urb(kbtab->irq, dev,
    163			 usb_rcvintpipe(dev, endpoint->bEndpointAddress),
    164			 kbtab->data, 8,
    165			 kbtab_irq, kbtab, endpoint->bInterval);
    166	kbtab->irq->transfer_dma = kbtab->data_dma;
    167	kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
    168
    169	error = input_register_device(kbtab->dev);
    170	if (error)
    171		goto fail3;
    172
    173	usb_set_intfdata(intf, kbtab);
    174
    175	return 0;
    176
    177 fail3:	usb_free_urb(kbtab->irq);
    178 fail2:	usb_free_coherent(dev, 8, kbtab->data, kbtab->data_dma);
    179 fail1:	input_free_device(input_dev);
    180	kfree(kbtab);
    181	return error;
    182}
    183
    184static void kbtab_disconnect(struct usb_interface *intf)
    185{
    186	struct kbtab *kbtab = usb_get_intfdata(intf);
    187	struct usb_device *udev = interface_to_usbdev(intf);
    188
    189	usb_set_intfdata(intf, NULL);
    190
    191	input_unregister_device(kbtab->dev);
    192	usb_free_urb(kbtab->irq);
    193	usb_free_coherent(udev, 8, kbtab->data, kbtab->data_dma);
    194	kfree(kbtab);
    195}
    196
    197static struct usb_driver kbtab_driver = {
    198	.name =		"kbtab",
    199	.probe =	kbtab_probe,
    200	.disconnect =	kbtab_disconnect,
    201	.id_table =	kbtab_ids,
    202};
    203
    204module_usb_driver(kbtab_driver);