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

tm6000-input.c (11473B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices
      4 *
      5 *  Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de>
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/init.h>
     10#include <linux/delay.h>
     11
     12#include <linux/input.h>
     13#include <linux/usb.h>
     14
     15#include <media/rc-core.h>
     16
     17#include "tm6000.h"
     18#include "tm6000-regs.h"
     19
     20static unsigned int ir_debug;
     21module_param(ir_debug, int, 0644);
     22MODULE_PARM_DESC(ir_debug, "debug message level");
     23
     24static unsigned int enable_ir = 1;
     25module_param(enable_ir, int, 0644);
     26MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)");
     27
     28static unsigned int ir_clock_mhz = 12;
     29module_param(ir_clock_mhz, int, 0644);
     30MODULE_PARM_DESC(ir_clock_mhz, "ir clock, in MHz");
     31
     32#define URB_SUBMIT_DELAY	100	/* ms - Delay to submit an URB request on retrial and init */
     33#define URB_INT_LED_DELAY	100	/* ms - Delay to turn led on again on int mode */
     34
     35#undef dprintk
     36
     37#define dprintk(level, fmt, arg...) do {\
     38	if (ir_debug >= level) \
     39		printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
     40	} while (0)
     41
     42struct tm6000_ir_poll_result {
     43	u16 rc_data;
     44};
     45
     46struct tm6000_IR {
     47	struct tm6000_core	*dev;
     48	struct rc_dev		*rc;
     49	char			name[32];
     50	char			phys[32];
     51
     52	/* poll expernal decoder */
     53	int			polling;
     54	struct delayed_work	work;
     55	u8			wait:1;
     56	u8			pwled:2;
     57	u8			submit_urb:1;
     58	struct urb		*int_urb;
     59
     60	/* IR device properties */
     61	u64			rc_proto;
     62};
     63
     64void tm6000_ir_wait(struct tm6000_core *dev, u8 state)
     65{
     66	struct tm6000_IR *ir = dev->ir;
     67
     68	if (!dev->ir)
     69		return;
     70
     71	dprintk(2, "%s: %i\n",__func__, ir->wait);
     72
     73	if (state)
     74		ir->wait = 1;
     75	else
     76		ir->wait = 0;
     77}
     78
     79static int tm6000_ir_config(struct tm6000_IR *ir)
     80{
     81	struct tm6000_core *dev = ir->dev;
     82	u32 pulse = 0, leader = 0;
     83
     84	dprintk(2, "%s\n",__func__);
     85
     86	/*
     87	 * The IR decoder supports RC-5 or NEC, with a configurable timing.
     88	 * The timing configuration there is not that accurate, as it uses
     89	 * approximate values. The NEC spec mentions a 562.5 unit period,
     90	 * and RC-5 uses a 888.8 period.
     91	 * Currently, driver assumes a clock provided by a 12 MHz XTAL, but
     92	 * a modprobe parameter can adjust it.
     93	 * Adjustments are required for other timings.
     94	 * It seems that the 900ms timing for NEC is used to detect a RC-5
     95	 * IR, in order to discard such decoding
     96	 */
     97
     98	switch (ir->rc_proto) {
     99	case RC_PROTO_BIT_NEC:
    100		leader = 900;	/* ms */
    101		pulse  = 700;	/* ms - the actual value would be 562 */
    102		break;
    103	default:
    104	case RC_PROTO_BIT_RC5:
    105		leader = 900;	/* ms - from the NEC decoding */
    106		pulse  = 1780;	/* ms - The actual value would be 1776 */
    107		break;
    108	}
    109
    110	pulse = ir_clock_mhz * pulse;
    111	leader = ir_clock_mhz * leader;
    112	if (ir->rc_proto == RC_PROTO_BIT_NEC)
    113		leader = leader | 0x8000;
    114
    115	dprintk(2, "%s: %s, %d MHz, leader = 0x%04x, pulse = 0x%06x \n",
    116		__func__,
    117		(ir->rc_proto == RC_PROTO_BIT_NEC) ? "NEC" : "RC-5",
    118		ir_clock_mhz, leader, pulse);
    119
    120	/* Remote WAKEUP = enable, normal mode, from IR decoder output */
    121	tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe);
    122
    123	/* Enable IR reception on non-busrt mode */
    124	tm6000_set_reg(dev, TM6010_REQ07_RD8_IR, 0x2f);
    125
    126	/* IR_WKUP_SEL = Low byte in decoded IR data */
    127	tm6000_set_reg(dev, TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff);
    128	/* IR_WKU_ADD code */
    129	tm6000_set_reg(dev, TM6010_REQ07_RDB_IR_WAKEUP_ADD, 0xff);
    130
    131	tm6000_set_reg(dev, TM6010_REQ07_RDC_IR_LEADER1, leader >> 8);
    132	tm6000_set_reg(dev, TM6010_REQ07_RDD_IR_LEADER0, leader);
    133
    134	tm6000_set_reg(dev, TM6010_REQ07_RDE_IR_PULSE_CNT1, pulse >> 8);
    135	tm6000_set_reg(dev, TM6010_REQ07_RDF_IR_PULSE_CNT0, pulse);
    136
    137	if (!ir->polling)
    138		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
    139	else
    140		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
    141	msleep(10);
    142
    143	/* Shows that IR is working via the LED */
    144	tm6000_flash_led(dev, 0);
    145	msleep(100);
    146	tm6000_flash_led(dev, 1);
    147	ir->pwled = 1;
    148
    149	return 0;
    150}
    151
    152static void tm6000_ir_keydown(struct tm6000_IR *ir,
    153			      const char *buf, unsigned int len)
    154{
    155	u8 device, command;
    156	u32 scancode;
    157	enum rc_proto protocol;
    158
    159	if (len < 1)
    160		return;
    161
    162	command = buf[0];
    163	device = (len > 1 ? buf[1] : 0x0);
    164	switch (ir->rc_proto) {
    165	case RC_PROTO_BIT_RC5:
    166		protocol = RC_PROTO_RC5;
    167		scancode = RC_SCANCODE_RC5(device, command);
    168		break;
    169	case RC_PROTO_BIT_NEC:
    170		protocol = RC_PROTO_NEC;
    171		scancode = RC_SCANCODE_NEC(device, command);
    172		break;
    173	default:
    174		protocol = RC_PROTO_OTHER;
    175		scancode = RC_SCANCODE_OTHER(device << 8 | command);
    176		break;
    177	}
    178
    179	dprintk(1, "%s, protocol: 0x%04x, scancode: 0x%08x\n",
    180		__func__, protocol, scancode);
    181	rc_keydown(ir->rc, protocol, scancode, 0);
    182}
    183
    184static void tm6000_ir_urb_received(struct urb *urb)
    185{
    186	struct tm6000_core *dev = urb->context;
    187	struct tm6000_IR *ir = dev->ir;
    188	char *buf;
    189
    190	dprintk(2, "%s\n",__func__);
    191	if (urb->status < 0 || urb->actual_length <= 0) {
    192		printk(KERN_INFO "tm6000: IR URB failure: status: %i, length %i\n",
    193		       urb->status, urb->actual_length);
    194		ir->submit_urb = 1;
    195		schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
    196		return;
    197	}
    198	buf = urb->transfer_buffer;
    199
    200	if (ir_debug)
    201		print_hex_dump(KERN_DEBUG, "tm6000: IR data: ",
    202			       DUMP_PREFIX_OFFSET,16, 1,
    203			       buf, urb->actual_length, false);
    204
    205	tm6000_ir_keydown(ir, urb->transfer_buffer, urb->actual_length);
    206
    207	usb_submit_urb(urb, GFP_ATOMIC);
    208	/*
    209	 * Flash the led. We can't do it here, as it is running on IRQ context.
    210	 * So, use the scheduler to do it, in a few ms.
    211	 */
    212	ir->pwled = 2;
    213	schedule_delayed_work(&ir->work, msecs_to_jiffies(10));
    214}
    215
    216static void tm6000_ir_handle_key(struct work_struct *work)
    217{
    218	struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
    219	struct tm6000_core *dev = ir->dev;
    220	int rc;
    221	u8 buf[2];
    222
    223	if (ir->wait)
    224		return;
    225
    226	dprintk(3, "%s\n",__func__);
    227
    228	rc = tm6000_read_write_usb(dev, USB_DIR_IN |
    229		USB_TYPE_VENDOR | USB_RECIP_DEVICE,
    230		REQ_02_GET_IR_CODE, 0, 0, buf, 2);
    231	if (rc < 0)
    232		return;
    233
    234	/* Check if something was read */
    235	if ((buf[0] & 0xff) == 0xff) {
    236		if (!ir->pwled) {
    237			tm6000_flash_led(dev, 1);
    238			ir->pwled = 1;
    239		}
    240		return;
    241	}
    242
    243	tm6000_ir_keydown(ir, buf, rc);
    244	tm6000_flash_led(dev, 0);
    245	ir->pwled = 0;
    246
    247	/* Re-schedule polling */
    248	schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
    249}
    250
    251static void tm6000_ir_int_work(struct work_struct *work)
    252{
    253	struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
    254	struct tm6000_core *dev = ir->dev;
    255	int rc;
    256
    257	dprintk(3, "%s, submit_urb = %d, pwled = %d\n",__func__, ir->submit_urb,
    258		ir->pwled);
    259
    260	if (ir->submit_urb) {
    261		dprintk(3, "Resubmit urb\n");
    262		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
    263
    264		rc = usb_submit_urb(ir->int_urb, GFP_ATOMIC);
    265		if (rc < 0) {
    266			printk(KERN_ERR "tm6000: Can't submit an IR interrupt. Error %i\n",
    267			       rc);
    268			/* Retry in 100 ms */
    269			schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
    270			return;
    271		}
    272		ir->submit_urb = 0;
    273	}
    274
    275	/* Led is enabled only if USB submit doesn't fail */
    276	if (ir->pwled == 2) {
    277		tm6000_flash_led(dev, 0);
    278		ir->pwled = 0;
    279		schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_INT_LED_DELAY));
    280	} else if (!ir->pwled) {
    281		tm6000_flash_led(dev, 1);
    282		ir->pwled = 1;
    283	}
    284}
    285
    286static int tm6000_ir_start(struct rc_dev *rc)
    287{
    288	struct tm6000_IR *ir = rc->priv;
    289
    290	dprintk(2, "%s\n",__func__);
    291
    292	schedule_delayed_work(&ir->work, 0);
    293
    294	return 0;
    295}
    296
    297static void tm6000_ir_stop(struct rc_dev *rc)
    298{
    299	struct tm6000_IR *ir = rc->priv;
    300
    301	dprintk(2, "%s\n",__func__);
    302
    303	cancel_delayed_work_sync(&ir->work);
    304}
    305
    306static int tm6000_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto)
    307{
    308	struct tm6000_IR *ir = rc->priv;
    309
    310	if (!ir)
    311		return 0;
    312
    313	dprintk(2, "%s\n",__func__);
    314
    315	ir->rc_proto = *rc_proto;
    316
    317	tm6000_ir_config(ir);
    318	/* TODO */
    319	return 0;
    320}
    321
    322static int __tm6000_ir_int_start(struct rc_dev *rc)
    323{
    324	struct tm6000_IR *ir = rc->priv;
    325	struct tm6000_core *dev;
    326	int pipe, size;
    327	int err = -ENOMEM;
    328
    329	if (!ir)
    330		return -ENODEV;
    331	dev = ir->dev;
    332
    333	dprintk(2, "%s\n",__func__);
    334
    335	ir->int_urb = usb_alloc_urb(0, GFP_ATOMIC);
    336	if (!ir->int_urb)
    337		return -ENOMEM;
    338
    339	pipe = usb_rcvintpipe(dev->udev,
    340		dev->int_in.endp->desc.bEndpointAddress
    341		& USB_ENDPOINT_NUMBER_MASK);
    342
    343	size = usb_maxpacket(dev->udev, pipe);
    344	dprintk(1, "IR max size: %d\n", size);
    345
    346	ir->int_urb->transfer_buffer = kzalloc(size, GFP_ATOMIC);
    347	if (!ir->int_urb->transfer_buffer) {
    348		usb_free_urb(ir->int_urb);
    349		return err;
    350	}
    351	dprintk(1, "int interval: %d\n", dev->int_in.endp->desc.bInterval);
    352
    353	usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
    354		ir->int_urb->transfer_buffer, size,
    355		tm6000_ir_urb_received, dev,
    356		dev->int_in.endp->desc.bInterval);
    357
    358	ir->submit_urb = 1;
    359	schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
    360
    361	return 0;
    362}
    363
    364static void __tm6000_ir_int_stop(struct rc_dev *rc)
    365{
    366	struct tm6000_IR *ir = rc->priv;
    367
    368	if (!ir || !ir->int_urb)
    369		return;
    370
    371	dprintk(2, "%s\n",__func__);
    372
    373	usb_kill_urb(ir->int_urb);
    374	kfree(ir->int_urb->transfer_buffer);
    375	usb_free_urb(ir->int_urb);
    376	ir->int_urb = NULL;
    377}
    378
    379int tm6000_ir_int_start(struct tm6000_core *dev)
    380{
    381	struct tm6000_IR *ir = dev->ir;
    382
    383	if (!ir)
    384		return 0;
    385
    386	return __tm6000_ir_int_start(ir->rc);
    387}
    388
    389void tm6000_ir_int_stop(struct tm6000_core *dev)
    390{
    391	struct tm6000_IR *ir = dev->ir;
    392
    393	if (!ir || !ir->rc)
    394		return;
    395
    396	__tm6000_ir_int_stop(ir->rc);
    397}
    398
    399int tm6000_ir_init(struct tm6000_core *dev)
    400{
    401	struct tm6000_IR *ir;
    402	struct rc_dev *rc;
    403	int err = -ENOMEM;
    404	u64 rc_proto;
    405
    406	if (!enable_ir)
    407		return -ENODEV;
    408
    409	if (!dev->caps.has_remote)
    410		return 0;
    411
    412	if (!dev->ir_codes)
    413		return 0;
    414
    415	ir = kzalloc(sizeof(*ir), GFP_ATOMIC);
    416	rc = rc_allocate_device(RC_DRIVER_SCANCODE);
    417	if (!ir || !rc)
    418		goto out;
    419
    420	dprintk(2, "%s\n", __func__);
    421
    422	/* record handles to ourself */
    423	ir->dev = dev;
    424	dev->ir = ir;
    425	ir->rc = rc;
    426
    427	/* input setup */
    428	rc->allowed_protocols = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_NEC;
    429	/* Needed, in order to support NEC remotes with 24 or 32 bits */
    430	rc->scancode_mask = 0xffff;
    431	rc->priv = ir;
    432	rc->change_protocol = tm6000_ir_change_protocol;
    433	if (dev->int_in.endp) {
    434		rc->open    = __tm6000_ir_int_start;
    435		rc->close   = __tm6000_ir_int_stop;
    436		INIT_DELAYED_WORK(&ir->work, tm6000_ir_int_work);
    437	} else {
    438		rc->open  = tm6000_ir_start;
    439		rc->close = tm6000_ir_stop;
    440		ir->polling = 50;
    441		INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key);
    442	}
    443
    444	snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
    445						dev->name);
    446
    447	usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
    448	strlcat(ir->phys, "/input0", sizeof(ir->phys));
    449
    450	rc_proto = RC_PROTO_BIT_UNKNOWN;
    451	tm6000_ir_change_protocol(rc, &rc_proto);
    452
    453	rc->device_name = ir->name;
    454	rc->input_phys = ir->phys;
    455	rc->input_id.bustype = BUS_USB;
    456	rc->input_id.version = 1;
    457	rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
    458	rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
    459	rc->map_name = dev->ir_codes;
    460	rc->driver_name = "tm6000";
    461	rc->dev.parent = &dev->udev->dev;
    462
    463	/* ir register */
    464	err = rc_register_device(rc);
    465	if (err)
    466		goto out;
    467
    468	return 0;
    469
    470out:
    471	dev->ir = NULL;
    472	rc_free_device(rc);
    473	kfree(ir);
    474	return err;
    475}
    476
    477int tm6000_ir_fini(struct tm6000_core *dev)
    478{
    479	struct tm6000_IR *ir = dev->ir;
    480
    481	/* skip detach on non attached board */
    482
    483	if (!ir)
    484		return 0;
    485
    486	dprintk(2, "%s\n",__func__);
    487
    488	if (!ir->polling)
    489		__tm6000_ir_int_stop(ir->rc);
    490
    491	tm6000_ir_stop(ir->rc);
    492
    493	/* Turn off the led */
    494	tm6000_flash_led(dev, 0);
    495	ir->pwled = 0;
    496
    497	rc_unregister_device(ir->rc);
    498
    499	kfree(ir);
    500	dev->ir = NULL;
    501
    502	return 0;
    503}