mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user