From b653b622a623f0e8e2c03af8254e6ac3d29b71c7 Mon Sep 17 00:00:00 2001 From: tmk Date: Sat, 4 Jun 2016 19:29:02 +0900 Subject: [PATCH] adb_usb: Add support for Apple Adjustable keybaord media keys --- converter/adb_usb/MEMO.txt | 27 +++++++++ converter/adb_usb/keymap_common.h | 22 +++---- converter/adb_usb/keymap_plain.c | 8 +-- converter/adb_usb/led.c | 2 +- converter/adb_usb/matrix.c | 95 ++++++++++++++++++++++++++----- 5 files changed, 124 insertions(+), 30 deletions(-) create mode 100644 converter/adb_usb/MEMO.txt diff --git a/converter/adb_usb/MEMO.txt b/converter/adb_usb/MEMO.txt new file mode 100644 index 00000000..f079442c --- /dev/null +++ b/converter/adb_usb/MEMO.txt @@ -0,0 +1,27 @@ +ADB keyboard handle id +====================== +0x01 Apple Standard keyboard M0116 ANSI +0x01 Apple Desktop Bus keyboard 658-4081 ANSI +0x02 Apple Extended Keyboard M0115 ANSI +0x02 Apple Extended Keyboard II M3501 ANSI +0x03 Logical id for Extended Protocol +0x10 Apple Adjustable keyboard M1242 ANSI + + +Adjustable Keyboard media key +============================= +Media key part has different address than the main keyboard(0x02). + +Device Address: 0x07(Appliances/Misc devices) +Handler ID: 0x02 + +Scan Codes +---------- +Media key ADB Code Code in Matix +----------------------------------------- +Volume Up: 0x03 0x48 +Volume Down: 0x02 0x49 +Mute: 0x01 0x4a +Mic: 0x00 0x42 + +As for these keys raw ADB codes are translate into logical codes in matrix. diff --git a/converter/adb_usb/keymap_common.h b/converter/adb_usb/keymap_common.h index 0a917cbc..cb643c8f 100644 --- a/converter/adb_usb/keymap_common.h +++ b/converter/adb_usb/keymap_common.h @@ -34,9 +34,9 @@ extern const uint16_t fn_actions[]; /* Common layout: ANSI+ISO - * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,---. - * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr| - * `---' `---------------' `---------------' `---------------' `-----------' `---' + * ,---. .---------------. ,---------------. ,---------------. ,-----------. ,---------------. + * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |VDn|VUp|Mut|Pwr| + * `---' `---------------' `---------------' `---------------' `-----------' `---------------' * ,-----------------------------------------------------------. ,-----------. ,---------------. * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| =| /| *| * |-----------------------------------------------------------| |-----------| |---------------| @@ -46,16 +46,16 @@ extern const uint16_t fn_actions[]; * |-----------------------------------------------------------| ,---. |---------------| * |Shif|\ | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| | * |-----------------------------------------------------------| ,-----------. |-----------|Ent| - * |Ctrl |Opt |Cmd | Space | |Opt |Ctrl | |Lef|Dow|Rig| | 0| .| | + * |Ctrl |Opt |Cmd | Space |App |Opt |Ctrl | |Lef|Dow|Rig| | 0| .| | * `-----------------------------------------------------------' `-----------' `---------------' */ #define KEYMAP( \ - K35, K7A,K78,K63,K76, K60,K61,K62,K64, K65,K6D,K67,K6F, K69,K6B,K71, K7F, \ + K35, K7A,K78,K63,K76, K60,K61,K62,K64, K65,K6D,K67,K6F, K69,K6B,K71, K49,K48,K4A,K7F, \ K32,K12,K13,K14,K15,K17,K16,K1A,K1C,K19,K1D,K1B,K18,K33, K72,K73,K74, K47,K51,K4B,K43, \ K30,K0C,K0D,K0E,K0F,K11,K10,K20,K22,K1F,K23,K21,K1E,K2A, K75,K77,K79, K59,K5B,K5C,K4E, \ K39,K00,K01,K02,K03,K05,K04,K26,K28,K25,K29,K27, K24, K56,K57,K58,K45, \ K38,K0A,K06,K07,K08,K09,K0B,K2D,K2E,K2B,K2F,K2C, K7B, K3E, K53,K54,K55, \ - K36,K3A,K37, K31, K7C,K7D, K3B,K3D,K3C, K52, K41,K4C \ + K36,K3A,K37, K31, K42,K7C,K7D, K3B,K3D,K3C, K52, K41,K4C \ ) { \ { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \ { KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E, KC_##K0F }, \ @@ -65,12 +65,12 @@ extern const uint16_t fn_actions[]; { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F }, \ { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_PENT, KC_##K35, KC_##K36, KC_##K37 }, \ { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_NO }, \ - { KC_F17, KC_##K41, KC_NO, KC_##K43, KC_F18, KC_##K45, KC_NO, KC_##K47 }, \ - { KC_NO, KC_NO, KC_NO, KC_##K4B, KC_##K4C, KC_NO, KC_##K4E, KC_F18 }, \ + { KC_F17, KC_##K41, KC_##K42, KC_##K43, KC_F18, KC_##K45, KC_NO, KC_##K47 }, \ + { KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_NO, KC_##K4E, KC_F18 }, \ { KC_F19, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \ - { KC_##K58, KC_##K59, KC_F20, KC_##K5B, KC_##K5C, KC_INT3, KC_INT1, KC_PCMM }, \ - { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_LANG2, KC_##K67 }, \ - { KC_LANG1, KC_##K69, KC_F16, KC_##K6B, KC_NO, KC_##K6D, KC_APP, KC_##K6F }, \ + { KC_##K58, KC_##K59, KC_F20, KC_##K5B, KC_##K5C, KC_JYEN, KC_RO, KC_PCMM }, \ + { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_HANJ, KC_##K67 }, \ + { KC_HAEN, KC_##K69, KC_F16, KC_##K6B, KC_NO, KC_##K6D, KC_APP, KC_##K6F }, \ { KC_NO, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \ { KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_NO, KC_##K7F } \ } diff --git a/converter/adb_usb/keymap_plain.c b/converter/adb_usb/keymap_plain.c index 433a5cb3..2f11f86a 100644 --- a/converter/adb_usb/keymap_plain.c +++ b/converter/adb_usb/keymap_plain.c @@ -19,20 +19,20 @@ */ const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = KEYMAP( - ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, NO, + ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, VOLD,VOLU,MUTE,NO, FN0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,EQL, PSLS,PAST, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,FN1, DEL, END, PGDN, P7, P8, P9, PMNS, LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3, - LCTL,LALT,LGUI, SPC, RALT,RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT + LCTL,LALT,LGUI, SPC, APP, RALT,RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT ), [1] = KEYMAP( - GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, NO, + GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, VOLD,VOLU,MUTE,NO, FN0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, INS, HOME,PGUP, NLCK,BTN1,BTN2,BTN3, TAB, Q, W, E, R, T, Y, U, PSCR,SLCK,PAUS,UP, INS, FN1, DEL, END, PGDN, WH_D,MS_U,WH_U,WH_D, LCAP,VOLD,VOLU,MUTE,F, G, H, J, HOME,PGUP,LEFT,RGHT, ENT, MS_L,MS_D,MS_R,WH_U, LSFT,NUBS,Z, X, C, V, B, N, M, END, PGDN,DOWN, RSFT, PGUP, WH_L,MS_D,WH_R, - LCTL,LGUI,LALT, SPC, RGUI,RCTL, HOME,PGDN,END, BTN1, BTN2,BTN3 + LCTL,LALT,LGUI, SPC, APP, RALT,RCTL, HOME,PGDN,END, BTN1, BTN2,BTN3 ), }; diff --git a/converter/adb_usb/led.c b/converter/adb_usb/led.c index 3ee64a8e..ea9bf77b 100644 --- a/converter/adb_usb/led.c +++ b/converter/adb_usb/led.c @@ -23,5 +23,5 @@ along with this program. If not, see . void led_set(uint8_t usb_led) { - adb_host_kbd_led(~usb_led); + adb_host_kbd_led(ADB_ADDR_KEYBOARD, ~usb_led); } diff --git a/converter/adb_usb/matrix.c b/converter/adb_usb/matrix.c index 12c3ada7..6190c71a 100644 --- a/converter/adb_usb/matrix.c +++ b/converter/adb_usb/matrix.c @@ -39,6 +39,7 @@ along with this program. If not, see . #endif +static bool has_media_keys = false; static bool is_iso_layout = false; static bool is_modified = false; static report_mouse_t mouse_report = {}; @@ -70,13 +71,26 @@ uint8_t matrix_cols(void) void matrix_init(void) { + // LED on + DDRD |= (1<<6); PORTD |= (1<<6); + adb_host_init(); // wait for keyboard to boot up and receive command - _delay_ms(1000); + _delay_ms(2000); + + // device scan + xprintf("Before init:\n"); + for (uint8_t addr = 1; addr < 16; addr++) { + uint16_t reg3 = adb_host_talk(addr, ADB_REG_3); + if (reg3) { + xprintf("Scan: addr:%d, reg3:%04X\n", addr, reg3); + } + _delay_ms(20); + } // Determine ISO keyboard by handler id // http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L815 - uint16_t handler_id = adb_host_talk(ADB_ADDR_KEYBOARD, 3); + uint16_t handler_id = adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_3); switch (handler_id) { case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D: case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1: @@ -88,11 +102,27 @@ void matrix_init(void) break; } + // Adjustable keyboard media keys: address=0x07 and handlerID=0x02 + has_media_keys = (0x02 == (adb_host_talk(ADB_ADDR_APPLIANCE, ADB_REG_3) & 0xff)); + if (has_media_keys) { + xprintf("Found: media keys\n"); + } + // Enable keyboard left/right modifier distinction - // Addr:Keyboard(0010), Cmd:Listen(10), Register3(11) - // upper byte: reserved bits 0000, device address 0010 - // lower byte: device handler 00000011 - adb_host_listen(0x2B,0x02,0x03); + // Listen Register3 + // upper byte: reserved bits 0000, keyboard address 0010 + // lower byte: device handler 00000011 + adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_3, ADB_ADDR_KEYBOARD, ADB_HANDLER_EXTENDED_PROTOCOL); + + // device scan + xprintf("After init:\n"); + for (uint8_t addr = 1; addr < 16; addr++) { + uint16_t reg3 = adb_host_talk(addr, ADB_REG_3); + if (reg3) { + xprintf("Scan: addr:%d, reg3:%04X\n", addr, reg3); + } + _delay_ms(20); + } // initialize matrix state: all keys off for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; @@ -103,14 +133,8 @@ void matrix_init(void) //debug_mouse = true; print("debug enabled.\n"); - // LED flash - DDRD |= (1<<6); PORTD |= (1<<6); - _delay_ms(500); + // LED off DDRD |= (1<<6); PORTD &= ~(1<<6); - - uint16_t handler_id2 = adb_host_talk(ADB_ADDR_KEYBOARD, 3); - xprintf("handler_id: %02X -> %02X\n", (handler_id & 0xff), (handler_id2 & 0xff)); - return; } @@ -192,7 +216,50 @@ uint8_t matrix_scan(void) if ( codes == 0xFFFF ) { _delay_ms(12); // delay for preventing overload of poor ADB keyboard controller - codes = adb_host_kbd_recv(); + codes = adb_host_kbd_recv(ADB_ADDR_KEYBOARD); + + // Adjustable keybaord media keys + if (codes == 0 && has_media_keys && + (codes = adb_host_kbd_recv(ADB_ADDR_APPLIANCE))) { + // key1 + switch (codes & 0x7f ) { + case 0x00: // Mic + codes = (codes & ~0x007f) | 0x42; + break; + case 0x01: // Mute + codes = (codes & ~0x007f) | 0x4a; + break; + case 0x02: // Volume down + codes = (codes & ~0x007f) | 0x49; + break; + case 0x03: // Volume Up + codes = (codes & ~0x007f) | 0x48; + break; + case 0x7F: // no code + break; + default: + xprintf("ERROR: media key1\n"); + return 0x11; + } + // key0 + switch ((codes >> 8) & 0x7f ) { + case 0x00: // Mic + codes = (codes & ~0x7f00) | (0x42 << 8); + break; + case 0x01: // Mute + codes = (codes & ~0x7f00) | (0x4a << 8); + break; + case 0x02: // Volume down + codes = (codes & ~0x7f00) | (0x49 << 8); + break; + case 0x03: // Volume Up + codes = (codes & ~0x7f00) | (0x48 << 8); + break; + default: + xprintf("ERROR: media key0\n"); + return 0x10; + } + } } key0 = codes>>8; key1 = codes&0xFF; -- 2.39.3