remote: add mouse function to 4.9

PD#154561: remote mouse function to 4.9

1. need execute remotecfg to config it
    remotecfg -t remote-mouse.tab
2. config exp, default to set 0xffff
    fn_key_scancode = 0x15 (ir scancode)
    cursor_left_scancode = 0x1c
    cursor_right_scancode = 0x48
    cursor_up_scancode = 0x44
    cursor_down_scancode = 0x1d
    cursor_ok_scancode = 0x5c
3. mv rc_common.h {include/uapi/linux => drivers/amlogic/input/remote}

Change-Id: I7f62e0d5a6dfaa1ad7f56358a30fd968f84b543a
Signed-off-by: Zan Peng <zan.peng@amlogic.com>
This commit is contained in:
Zan Peng
2017-11-29 16:48:40 +08:00
committed by Jianxin Pan
parent f6a4349c69
commit 6b4b9550ba
7 changed files with 164 additions and 16 deletions

View File

@@ -14151,3 +14151,7 @@ F: arch/arm64/boot/dts/amlogic/gxl_p241_v2-1g.dts
AMLOGIC lcd driver
M: Evoke Zhang <evoke.zhang@amlogic.com>
F: drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TV070WSM.c
AMLOGIC remote
M: Zan Peng <zan.peng@amlogic.com>
F: {include/uapi/linux => drivers/amlogic/input/remote}/rc_common.h

View File

@@ -14,7 +14,7 @@
#define CUSTOM_NAME_LEN 64
/*to ensure kernel and user spase use the same header file*/
#define SHARE_DATA_VERSION "v1.0.0"
#define SHARE_DATA_VERSION "v1.1.0"
union _codemap {
struct ir_key_map {
@@ -23,10 +23,31 @@ union _codemap {
} map;
__u32 code;
};
/*
*struct cursor_codemap - codemap for mouse mode
*
*@fn_key_scancode: scancode of fn key which used to swith mode
*@cursor_left_scancode: scancode of left key
*@cursor_right_scancode: scancode of right key
*@cursor_up_scancode: scancode of up key
*@cursor_down_scancode: scancode of down key
*@cursor_ok_scancode: scancode of ok key
*/
struct cursor_codemap {
__u16 fn_key_scancode;
__u16 cursor_left_scancode;
__u16 cursor_right_scancode;
__u16 cursor_up_scancode;
__u16 cursor_down_scancode;
__u16 cursor_ok_scancode;
};
/**
*struct ir_map_table - the IR key map table for different remote-control
*
*@custom_name: table name
*@cursor_code: mouse mode need
*@map_size: number of IR key
*@custom_code: custom code, identify different key mapping table
*@release_delay: release delay time
@@ -34,6 +55,7 @@ union _codemap {
*/
struct ir_map_tab {
char custom_name[CUSTOM_NAME_LEN];
struct cursor_codemap cursor_code;
__u16 map_size;
__u32 custom_code;
__u32 release_delay;

View File

@@ -125,6 +125,20 @@ void remote_keydown(struct remote_dev *dev, int scancode, int status)
dev->cur_hardcode);
}
spin_lock_irqsave(&dev->keylock, flags);
/**
*only a few keys which be set in key map table support
*report relative axes event in mouse mode, other keys
*will continue to report key event.
*/
if (status == REMOTE_NORMAL ||
status == REMOTE_REPEAT) {
/*to report relative axes event*/
if (dev->ir_report_rel(dev, scancode, status) == 0) {
spin_unlock_irqrestore(&dev->keylock, flags);
return;
}
}
if (status == REMOTE_NORMAL) {
keycode = dev->getkeycode(dev, scancode);
if (keycode == KEY_POWER)
@@ -190,6 +204,16 @@ int remote_register_device(struct remote_dev *dev)
for (i = KEY_OK; i < BTN_TRIGGER_HAPPY; i++)
__set_bit(i, dev->input_device->keybit);
__set_bit(BTN_MOUSE, dev->input_device->keybit);
__set_bit(BTN_LEFT, dev->input_device->keybit);
__set_bit(BTN_RIGHT, dev->input_device->keybit);
__set_bit(BTN_MIDDLE, dev->input_device->keybit);
__set_bit(EV_REL, dev->input_device->evbit);
__set_bit(REL_X, dev->input_device->relbit);
__set_bit(REL_Y, dev->input_device->relbit);
__set_bit(REL_WHEEL, dev->input_device->relbit);
dev->input_device->keycodesize = sizeof(unsigned short);
dev->input_device->keycodemax = 0x1ff;
@@ -221,4 +245,3 @@ EXPORT_SYMBOL(remote_unregister_device);
MODULE_AUTHOR("AMLOGIC");
MODULE_DESCRIPTION("Remote Driver");
MODULE_LICENSE("GPL");

View File

@@ -88,10 +88,11 @@ struct remote_dev {
int debug_buffer_size;
int debug_current;
u32 (*getkeycode)(struct remote_dev *dev, u32 scancode);
bool (*set_custom_code)(struct remote_dev *dev, u32 code);
bool (*is_valid_custom)(struct remote_dev *dev);
bool (*is_next_repeat)(struct remote_dev *dev);
u32 (*getkeycode)(struct remote_dev *, u32);
int (*ir_report_rel)(struct remote_dev *, u32, int);
bool (*set_custom_code)(struct remote_dev *, u32);
bool (*is_valid_custom)(struct remote_dev *);
bool (*is_next_repeat)(struct remote_dev *);
};
struct remote_raw_handle {
@@ -205,5 +206,3 @@ bool remote_debug_get_enable(void);
int debug_log_printk(struct remote_dev *dev, const char *fmt);
#endif

View File

@@ -136,6 +136,60 @@ static int ir_lookup_by_scancode(struct ir_map_tab *ir_map,
return -1;
}
static int ir_report_rel(struct remote_dev *dev, u32 scancode, int status)
{
struct remote_chip *chip = (struct remote_chip *)dev->platform_data;
struct ir_map_tab_list *ct = chip->cur_tab;
static u32 repeat_count;
s32 cursor_value = 0;
u32 valid_scancode;
u16 mouse_code;
s32 move_accelerate[] = CURSOR_MOVE_ACCELERATE;
/*nothing need to do in normal mode*/
if (!ct || (ct->ir_dev_mode != MOUSE_MODE))
return -EINVAL;
if (status == REMOTE_REPEAT) {
valid_scancode = dev->last_scancode;
repeat_count++;
if (repeat_count > ARRAY_SIZE(move_accelerate) - 1)
repeat_count = ARRAY_SIZE(move_accelerate) - 1;
} else {
valid_scancode = scancode;
dev->last_scancode = scancode;
repeat_count = 0;
}
if (valid_scancode == ct->tab.cursor_code.cursor_left_scancode) {
cursor_value = -(1 + move_accelerate[repeat_count]);
mouse_code = REL_X;
} else if (valid_scancode ==
ct->tab.cursor_code.cursor_right_scancode) {
cursor_value = 1 + move_accelerate[repeat_count];
mouse_code = REL_X;
} else if (valid_scancode ==
ct->tab.cursor_code.cursor_up_scancode) {
cursor_value = -(1 + move_accelerate[repeat_count]);
mouse_code = REL_Y;
} else if (valid_scancode ==
ct->tab.cursor_code.cursor_down_scancode) {
cursor_value = 1 + move_accelerate[repeat_count];
mouse_code = REL_Y;
} else {
return -EINVAL;
}
input_event(chip->r_dev->input_device, EV_REL,
mouse_code, cursor_value);
input_sync(chip->r_dev->input_device);
remote_dbg(chip->dev, "mouse cursor be %s moved %d.\n",
mouse_code == REL_X ? "horizontal" :
"vertical",
cursor_value);
return 0;
}
static u32 getkeycode(struct remote_dev *dev, u32 scancode)
{
struct remote_chip *chip = (struct remote_chip *)dev->platform_data;
@@ -146,13 +200,36 @@ static u32 getkeycode(struct remote_dev *dev, u32 scancode)
dev_err(chip->dev, "cur_custom is nulll\n");
return KEY_RESERVED;
}
/*return BTN_LEFT in mouse mode*/
if (ct->ir_dev_mode == MOUSE_MODE &&
scancode == ct->tab.cursor_code.cursor_ok_scancode) {
remote_dbg(chip->dev, "mouse left button scancode: 0x%x",
BTN_LEFT);
return BTN_LEFT;
}
index = ir_lookup_by_scancode(&ct->tab, scancode);
if (index < 0) {
dev_err(chip->dev, "scancode %d undefined\n", scancode);
return KEY_RESERVED;
}
/*save remote-control work mode*/
if (dev->keypressed == false &&
scancode == ct->tab.cursor_code.fn_key_scancode) {
if (ct->ir_dev_mode == NORMAL_MODE)
ct->ir_dev_mode = MOUSE_MODE;
else
ct->ir_dev_mode = NORMAL_MODE;
dev_info(chip->dev, "remote control[ID: 0x%x] switch to %s\n",
ct->tab.custom_code,
ct->ir_dev_mode ?
"mouse mode":"normal mode");
}
return ct->tab.codemap[index].map.keycode;
}
static bool is_valid_custom(struct remote_dev *dev)
{
struct remote_chip *chip = (struct remote_chip *)dev->platform_data;
@@ -371,6 +448,8 @@ static int get_custom_tables(struct device_node *node,
goto err;
}
memset(&ptable->tab.cursor_code, 0xff,
sizeof(struct cursor_codemap));
ir_scancode_sort(&ptable->tab);
/*insert list*/
spin_lock_irqsave(&chip->slock, flags);
@@ -540,6 +619,7 @@ static int remote_probe(struct platform_device *pdev)
chip->r_dev->dev = &pdev->dev;
chip->r_dev->platform_data = (void *)chip;
chip->r_dev->getkeycode = getkeycode;
chip->r_dev->ir_report_rel = ir_report_rel;
chip->r_dev->set_custom_code = set_custom_code;
chip->r_dev->is_valid_custom = is_valid_custom;
chip->r_dev->is_next_repeat = is_next_repeat;
@@ -689,4 +769,3 @@ module_exit(remote_exit);
MODULE_AUTHOR("AMLOGIC");
MODULE_DESCRIPTION("AMLOGIC REMOTE PROTOCOL");
MODULE_LICENSE("GPL");

View File

@@ -18,7 +18,7 @@
#ifndef _REMOTE_MESON_H
#define _REMOTE_MESON_H
#include <linux/cdev.h>
#include <uapi/linux/rc_common.h>
#include "rc_common.h"
#include "remote_core.h"
#define DRIVER_NAME "meson-remote"
@@ -26,12 +26,19 @@
#define IR_DATA_IS_VALID(data) (data & 0x8)
#define IR_CONTROLLER_BUSY(x) ((x >> 7) & 0x1)
#define CURSOR_MOVE_ACCELERATE {0, 2, 2, 4, 4, 6, 8, 10, 12, 14, 16, 18}
enum IR_CONTR_NUMBER {
MULTI_IR_ID = 0,
LEGACY_IR_ID,
IR_ID_MAX
};
enum IR_WORK_MODE {
NORMAL_MODE = 0,
MOUSE_MODE = 1
};
struct remote_range {
struct range active;
struct range idle;
@@ -47,7 +54,15 @@ struct remote_reg_map {
unsigned int val;
};
/*
*struct ir_map_tab_list
*
*@ir_dev_mode: 0: normal mode; 1: mouse mode
*@list:
*@tab:
*/
struct ir_map_tab_list {
bool ir_dev_mode;
struct list_head list;
struct ir_map_tab tab;
};
@@ -185,6 +200,3 @@ struct ir_map_tab_list *seek_map_tab(struct remote_chip *chip, int custom_code);
void ir_tab_free(struct ir_map_tab_list *ir_map_list);
#endif

View File

@@ -106,6 +106,18 @@ static ssize_t keymap_show(struct device *dev,
len += sprintf(buf+len, "release_delay=%d\n",
map_tab->tab.release_delay);
len += sprintf(buf+len, "map_size=%d\n", map_tab->tab.map_size);
len += sprintf(buf+len, "fn_key_scancode = 0x%x\n",
map_tab->tab.cursor_code.fn_key_scancode);
len += sprintf(buf+len, "cursor_left_scancode = 0x%x\n",
map_tab->tab.cursor_code.cursor_left_scancode);
len += sprintf(buf+len, "cursor_right_scancode = 0x%x\n",
map_tab->tab.cursor_code.cursor_right_scancode);
len += sprintf(buf+len, "cursor_up_scancode = 0x%x\n",
map_tab->tab.cursor_code.cursor_up_scancode);
len += sprintf(buf+len, "cursor_down_scancode = 0x%x\n",
map_tab->tab.cursor_code.cursor_down_scancode);
len += sprintf(buf+len, "cursor_ok_scancode = 0x%x\n",
map_tab->tab.cursor_code.cursor_ok_scancode);
len += sprintf(buf+len, "keycode scancode\n");
for (i = 0; i < map_tab->tab.map_size; i++) {
len += sprintf(buf+len, "%4d %4d\n",
@@ -283,6 +295,3 @@ void ir_sys_device_attribute_sys(struct remote_chip *chip)
device_destroy(&remote_class, chip->chr_devno);
}
EXPORT_SYMBOL_GPL(ir_sys_device_attribute_sys);