@@ 49,9 49,12 @@
/* structs */
struct ppbbq10_data {
- unsigned int is_symed;
- unsigned short keymap_norm[NUM_KEYCODES];
- short keymap_sym[NUM_KEYCODES];
+ unsigned short int mod_held;
+ unsigned short int mod_tapmodifier; // TODO: []mod_tapmodifier for multiple prefixes
+ unsigned int layer;
+ short layer_0[NUM_KEYCODES];
+ short layer_1[NUM_KEYCODES];
+
struct i2c_client *client;
struct input_dev *input;
};
@@ 73,7 76,7 @@ static int ppbbq10_write_reg(struct ppbbq10_data *drv_data, u8 reg);
/* variables */
-static unsigned short keymap_norm[NUM_KEYCODES] = {
+static unsigned short layer_0[NUM_KEYCODES] = {
[0x01] = KEY_UP,
[0x02] = KEY_DOWN,
[0x03] = KEY_LEFT,
@@ 84,6 87,7 @@ static unsigned short keymap_norm[NUM_KEYCODES] = {
[26] = KEY_LEFTALT,
[27] = KEY_LEFTSHIFT,
[28] = KEY_LEFTCTRL,
+ [29] = KEY_YEN,
['A'] = KEY_A,
['B'] = KEY_B,
['C'] = KEY_C,
@@ 111,12 115,12 @@ static unsigned short keymap_norm[NUM_KEYCODES] = {
['Y'] = KEY_Y,
['Z'] = KEY_Z,
[' '] = KEY_SPACE,
- ['~'] = KEY_0,
- ['$'] = KEY_GRAVE,
+ ['~'] = KEY_ESC,
+ ['$'] = KEY_TAB,
['\b'] = KEY_BACKSPACE,
['\n'] = KEY_ENTER,
};
-static short keymap_sym[NUM_KEYCODES] = {
+static short layer_1[NUM_KEYCODES] = {
[0x01] = KEY_UP,
[0x02] = KEY_DOWN,
[0x03] = KEY_LEFT,
@@ 127,37 131,39 @@ static short keymap_sym[NUM_KEYCODES] = {
[26] = KEY_LEFTALT,
[27] = KEY_LEFTSHIFT,
[28] = KEY_LEFTCTRL,
- ['A'] = KEY_A,
+ [29] = KEY_YEN,
+ ['A'] = KEY_8 * -1, // (*)
['B'] = KEY_1 * -1, // (!)
['C'] = KEY_9,
['D'] = KEY_5,
['E'] = KEY_2,
['F'] = KEY_6,
- ['G'] = KEY_G,
- ['H'] = KEY_H,
- ['I'] = KEY_I,
- ['J'] = KEY_J,
- ['K'] = KEY_K,
- ['L'] = KEY_L,
- ['M'] = KEY_M,
- ['N'] = KEY_N,
- ['O'] = KEY_O,
- ['P'] = KEY_P,
- ['Q'] = KEY_Q,
+ ['G'] = KEY_SLASH,
+ ['H'] = KEY_SEMICOLON * -1, // (:)
+ ['I'] = KEY_MINUS,
+ ['J'] = KEY_SEMICOLON,
+ ['K'] = KEY_APOSTROPHE,
+ ['L'] = KEY_APOSTROPHE * -1, // (")
+ ['M'] = KEY_DOT,
+ ['N'] = KEY_COMMA,
+ ['O'] = KEY_EQUAL * -1, // (+)
+ ['P'] = KEY_2 * -1, // (@)
+ ['Q'] = KEY_3 * -1, // (#)
['R'] = KEY_3,
['S'] = KEY_4,
- ['T'] = KEY_T,
- ['U'] = KEY_U,
+ ['T'] = KEY_9 * -1, // (()
+ ['U'] = KEY_MINUS * -1, // (_)
['W'] = KEY_1,
- ['V'] = KEY_V,
+ ['V'] = KEY_SLASH * -1, // (?)
['X'] = KEY_8,
- ['Y'] = KEY_Y,
+ ['Y'] = KEY_0 * -1, // ())
['Z'] = KEY_7,
- [' '] = KEY_SPACE,
- ['~'] = KEY_0,
- ['$'] = KEY_GRAVE,
- ['\b'] = KEY_BACKSPACE,
- ['\n'] = KEY_ENTER,
+
+ [' '] = KEY_DOWN,
+ ['~'] = KEY_UP,
+ ['$'] = KEY_LEFT,
+ ['\b'] = KEY_TAB,
+ ['\n'] = KEY_RIGHT,
};
static struct i2c_board_info ppbbq10_i2c_board_info[] __initdata = {
{ I2C_BOARD_INFO("ppbbq10", 0x1f), /*.irq = gpio_to_irq(11)*/ }
@@ 279,9 285,9 @@ ppbbq10_probe(struct i2c_client *client)
return -ENOMEM;
drv_data->client = client;
- memcpy(drv_data->keymap_norm, keymap_norm, sizeof(drv_data->keymap_norm));
- memcpy(drv_data->keymap_sym, keymap_sym, sizeof(drv_data->keymap_sym));
- drv_data->is_symed = 0;
+ memcpy(drv_data->layer_0, layer_0, sizeof(drv_data->layer_0));
+ memcpy(drv_data->layer_1, layer_1, sizeof(drv_data->layer_1));
+ drv_data->layer = 0;
error = ppbbq10_write_reg(drv_data, REG_RST);
if (error)
@@ 318,20 324,23 @@ ppbbq10_probe(struct i2c_client *client)
return -ENOMEM;
drv_data->input = input;
+ drv_data->mod_held = 0;
+ drv_data->mod_tapmodifier = 0;
+ drv_data->layer = 0;
input->name = client->name;
input->id.bustype = BUS_I2C;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0001;
- input->keycode = drv_data->keymap_norm;
- input->keycodesize = sizeof(drv_data->keymap_norm[0]);
- input->keycodemax = ARRAY_SIZE(drv_data->keymap_norm) + ARRAY_SIZE(drv_data->keymap_sym) ;
+ input->keycode = drv_data->layer_0;
+ input->keycodesize = sizeof(drv_data->layer_0[0]);
+ input->keycodemax = ARRAY_SIZE(drv_data->layer_0) + ARRAY_SIZE(drv_data->layer_1) ;
for (i = 0; i < NUM_KEYCODES; i++)
- __set_bit(drv_data->keymap_norm[i], input->keybit);
+ __set_bit(drv_data->layer_0[i], input->keybit);
for (i = 0; i < NUM_KEYCODES; i++)
- __set_bit(drv_data->keymap_sym[i], input->keybit);
+ __set_bit(drv_data->layer_1[i], input->keybit);
__clear_bit(KEY_RESERVED, input->keybit);
@@ 363,7 372,6 @@ ppbbq10_read_fifo(struct ppbbq10_data *drv_data)
{
struct input_dev *input = drv_data->input;
struct i2c_client *client = drv_data->client;
- unsigned int keycode;
u8 data[2];
u8 count;
int error;
@@ 387,6 395,9 @@ ppbbq10_read_fifo(struct ppbbq10_data *drv_data)
return;
}
count -= 1;
+
+ if (data[0] == STATE_PRESS || data[0] == STATE_RELEASE && data[1] != 29)
+ input_event(input, EV_MSC, MSC_SCAN, data[1]);
ppbbq10_report_keyevent(drv_data, data[0], data[1]);
}
@@ 416,47 427,51 @@ ppbbq10_read_reg(struct ppbbq10_data *drv_data, u8 reg, u8 *buf, u8 len)
}
static void
-ppbbq10_report_keyevent(struct ppbbq10_data *drv_data, u8 keystate, u8 keycode)
+ppbbq10_report_keyevent(struct ppbbq10_data *drv_data, u8 key_state, u8 key_code)
{
unsigned int key_mapped;
- int send_shift = 0;
+ printk(KERN_INFO "%s key %d/%c, state: %d\n", __func__, key_code, key_code, key_state);
- printk(KERN_INFO "%s key %d/%c, state: %d\n", __func__, keycode, keycode, keystate);
-
- // Determine key_mapped
- if (drv_data->is_symed) {
- send_shift = drv_data->keymap_sym[keycode] < 0;
- key_mapped = abs(drv_data->keymap_sym[keycode]);
- if (drv_data->is_symed && keystate == STATE_RELEASE) drv_data->is_symed = 0;
- printk(KERN_INFO "Sending sym'd: %s key %d/%c, state: %d and !! %d and is_shifted %d\n", __func__, keycode, keycode, keystate, drv_data->keymap_sym[keycode], send_shift);
+ // Map raw key_code to mapped key, if sym is tapped modifier or held,
+ // prime shift as the tapped modifier is mapped key < 0
+ if (drv_data->mod_held == KEY_YEN || drv_data->mod_tapmodifier == KEY_YEN) {
+ key_mapped = abs(drv_data->layer_1[key_code]);
+ drv_data->mod_tapmodifier = drv_data->layer_1[key_code] < 0 ? KEY_LEFTSHIFT : 0;
} else {
- key_mapped = drv_data->keymap_norm[keycode];
+ key_mapped = drv_data->layer_0[key_code];
}
- // Reset is_symed after 1 keypress
- if (drv_data->is_symed && keystate == STATE_RELEASE) drv_data->is_symed = 0;
-
- // Symbol layer tap, activates symbol for next pressed key
- if (keycode == 29 && keystate == STATE_RELEASE) {
- printk(KERN_INFO "SYM press - next key symbol.\n");
- drv_data->is_symed = 1;
- } else if (keystate == STATE_PRESS || keystate == STATE_RELEASE) {
- input_event(drv_data->input, EV_MSC, MSC_SCAN, key_mapped);
- if (key_mapped == KEY_UNKNOWN) {
- pr_warn("%s code 0x%02X UNKNOWN\n", __func__, key_mapped);
- } else if (drv_data->is_symed && send_shift) {
- ppbbq10_report_keyevent(drv_data, STATE_PRESS, 27);
- usleep_range(10, 20);
- ppbbq10_report_keyevent(drv_data, STATE_HOLD, 27);
- usleep_range(10, 20);
- input_report_key(drv_data->input, key_mapped, keystate == STATE_PRESS);
- usleep_range(10, 20);
- input_report_key(drv_data->input, key_mapped, keystate == STATE_RELEASE);
- usleep_range(10, 20);
- ppbbq10_report_keyevent(drv_data, STATE_RELEASE, 27);
- } else if ((drv_data->is_symed&& !send_shift) || !drv_data->is_symed) {
- input_report_key(drv_data->input, key_mapped, keystate == STATE_PRESS);
+ // If pressing a modifier
+ if (key_mapped == KEY_UNKNOWN) {
+ pr_warn("%s code 0x%02X UNKNOWN - not mapped\n", __func__, key_mapped);
+ } else if (
+ key_mapped == KEY_LEFTALT ||
+ key_mapped == KEY_LEFTSHIFT ||
+ key_mapped == KEY_LEFTCTRL ||
+ key_mapped == KEY_YEN
+ ) {
+ if (key_mapped != KEY_YEN && key_state != STATE_HOLD) {
+ printk(KERN_INFO "Registering modifier key: [%c], e.g. keymapped [%d] with state [%d]\n", key_code, key_mapped, key_state);
+ input_report_key(drv_data->input, key_mapped, key_state == STATE_PRESS);
+ }
+
+ if (key_state == STATE_HOLD) {
+ drv_data->mod_held = key_mapped;
+ } else if (key_state == STATE_RELEASE && drv_data->mod_held == 0) {
+ drv_data->mod_tapmodifier = key_mapped;
+ } else if (key_state == STATE_RELEASE) {
+ drv_data->mod_held = 0;
}
+ } else if (drv_data->mod_tapmodifier && key_state == STATE_RELEASE) {
+ printk(KERN_INFO "Registering key [%c] with tap modifier [%d]\n", key_code, drv_data->mod_tapmodifier);
+ input_report_key(drv_data->input, drv_data->mod_tapmodifier, 1);
+ input_report_key(drv_data->input, key_mapped, 1);
+ input_report_key(drv_data->input, key_mapped, 0);
+ input_report_key(drv_data->input, drv_data->mod_tapmodifier, 0);
+ drv_data->mod_tapmodifier = 0;
+ } else if (drv_data->mod_tapmodifier == 0 && key_state != STATE_HOLD) {
+ printk(KERN_INFO "Registering key normally: [%c] w state [%d]\n", key_code, key_state);
+ input_report_key(drv_data->input, key_mapped, key_state == STATE_PRESS);
}
}