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

firedtv-rc.c (3854B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * FireDTV driver (formerly known as FireSAT)
      4 *
      5 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
      6 */
      7
      8#include <linux/bitops.h>
      9#include <linux/input.h>
     10#include <linux/kernel.h>
     11#include <linux/slab.h>
     12#include <linux/string.h>
     13#include <linux/types.h>
     14#include <linux/workqueue.h>
     15
     16#include "firedtv.h"
     17
     18/* fixed table with older keycodes, geared towards MythTV */
     19static const u16 oldtable[] = {
     20
     21	/* code from device: 0x4501...0x451f */
     22
     23	KEY_ESC,
     24	KEY_F9,
     25	KEY_1,
     26	KEY_2,
     27	KEY_3,
     28	KEY_4,
     29	KEY_5,
     30	KEY_6,
     31	KEY_7,
     32	KEY_8,
     33	KEY_9,
     34	KEY_I,
     35	KEY_0,
     36	KEY_ENTER,
     37	KEY_RED,
     38	KEY_UP,
     39	KEY_GREEN,
     40	KEY_F10,
     41	KEY_SPACE,
     42	KEY_F11,
     43	KEY_YELLOW,
     44	KEY_DOWN,
     45	KEY_BLUE,
     46	KEY_Z,
     47	KEY_P,
     48	KEY_PAGEDOWN,
     49	KEY_LEFT,
     50	KEY_W,
     51	KEY_RIGHT,
     52	KEY_P,
     53	KEY_M,
     54
     55	/* code from device: 0x4540...0x4542 */
     56
     57	KEY_R,
     58	KEY_V,
     59	KEY_C,
     60};
     61
     62/* user-modifiable table for a remote as sold in 2008 */
     63static const u16 keytable[] = {
     64
     65	/* code from device: 0x0300...0x031f */
     66
     67	[0x00] = KEY_POWER,
     68	[0x01] = KEY_SLEEP,
     69	[0x02] = KEY_STOP,
     70	[0x03] = KEY_OK,
     71	[0x04] = KEY_RIGHT,
     72	[0x05] = KEY_1,
     73	[0x06] = KEY_2,
     74	[0x07] = KEY_3,
     75	[0x08] = KEY_LEFT,
     76	[0x09] = KEY_4,
     77	[0x0a] = KEY_5,
     78	[0x0b] = KEY_6,
     79	[0x0c] = KEY_UP,
     80	[0x0d] = KEY_7,
     81	[0x0e] = KEY_8,
     82	[0x0f] = KEY_9,
     83	[0x10] = KEY_DOWN,
     84	[0x11] = KEY_TITLE,	/* "OSD" - fixme */
     85	[0x12] = KEY_0,
     86	[0x13] = KEY_F20,	/* "16:9" - fixme */
     87	[0x14] = KEY_SCREEN,	/* "FULL" - fixme */
     88	[0x15] = KEY_MUTE,
     89	[0x16] = KEY_SUBTITLE,
     90	[0x17] = KEY_RECORD,
     91	[0x18] = KEY_TEXT,
     92	[0x19] = KEY_AUDIO,
     93	[0x1a] = KEY_RED,
     94	[0x1b] = KEY_PREVIOUS,
     95	[0x1c] = KEY_REWIND,
     96	[0x1d] = KEY_PLAYPAUSE,
     97	[0x1e] = KEY_NEXT,
     98	[0x1f] = KEY_VOLUMEUP,
     99
    100	/* code from device: 0x0340...0x0354 */
    101
    102	[0x20] = KEY_CHANNELUP,
    103	[0x21] = KEY_F21,	/* "4:3" - fixme */
    104	[0x22] = KEY_TV,
    105	[0x23] = KEY_DVD,
    106	[0x24] = KEY_VCR,
    107	[0x25] = KEY_AUX,
    108	[0x26] = KEY_GREEN,
    109	[0x27] = KEY_YELLOW,
    110	[0x28] = KEY_BLUE,
    111	[0x29] = KEY_CHANNEL,	/* "CH.LIST" */
    112	[0x2a] = KEY_VENDOR,	/* "CI" - fixme */
    113	[0x2b] = KEY_VOLUMEDOWN,
    114	[0x2c] = KEY_CHANNELDOWN,
    115	[0x2d] = KEY_LAST,
    116	[0x2e] = KEY_INFO,
    117	[0x2f] = KEY_FORWARD,
    118	[0x30] = KEY_LIST,
    119	[0x31] = KEY_FAVORITES,
    120	[0x32] = KEY_MENU,
    121	[0x33] = KEY_EPG,
    122	[0x34] = KEY_EXIT,
    123};
    124
    125int fdtv_register_rc(struct firedtv *fdtv, struct device *dev)
    126{
    127	struct input_dev *idev;
    128	int i, err;
    129
    130	idev = input_allocate_device();
    131	if (!idev)
    132		return -ENOMEM;
    133
    134	fdtv->remote_ctrl_dev = idev;
    135	idev->name = "FireDTV remote control";
    136	idev->dev.parent = dev;
    137	idev->evbit[0] = BIT_MASK(EV_KEY);
    138	idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL);
    139	if (!idev->keycode) {
    140		err = -ENOMEM;
    141		goto fail;
    142	}
    143	idev->keycodesize = sizeof(keytable[0]);
    144	idev->keycodemax = ARRAY_SIZE(keytable);
    145
    146	for (i = 0; i < ARRAY_SIZE(keytable); i++)
    147		set_bit(keytable[i], idev->keybit);
    148
    149	err = input_register_device(idev);
    150	if (err)
    151		goto fail_free_keymap;
    152
    153	return 0;
    154
    155fail_free_keymap:
    156	kfree(idev->keycode);
    157fail:
    158	input_free_device(idev);
    159	return err;
    160}
    161
    162void fdtv_unregister_rc(struct firedtv *fdtv)
    163{
    164	cancel_work_sync(&fdtv->remote_ctrl_work);
    165	kfree(fdtv->remote_ctrl_dev->keycode);
    166	input_unregister_device(fdtv->remote_ctrl_dev);
    167}
    168
    169void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code)
    170{
    171	struct input_dev *idev = fdtv->remote_ctrl_dev;
    172	u16 *keycode = idev->keycode;
    173
    174	if (code >= 0x0300 && code <= 0x031f)
    175		code = keycode[code - 0x0300];
    176	else if (code >= 0x0340 && code <= 0x0354)
    177		code = keycode[code - 0x0320];
    178	else if (code >= 0x4501 && code <= 0x451f)
    179		code = oldtable[code - 0x4501];
    180	else if (code >= 0x4540 && code <= 0x4542)
    181		code = oldtable[code - 0x4521];
    182	else {
    183		dev_dbg(fdtv->device,
    184			"invalid key code 0x%04x from remote control\n",
    185			code);
    186		return;
    187	}
    188
    189	input_report_key(idev, code, 1);
    190	input_sync(idev);
    191	input_report_key(idev, code, 0);
    192	input_sync(idev);
    193}