adb_usb: Add support for Apple Adjustable keybaord media keys
This commit is contained in:
parent
230ed4bdef
commit
b653b622a6
27
converter/adb_usb/MEMO.txt
Normal file
27
converter/adb_usb/MEMO.txt
Normal file
@ -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.
|
@ -34,9 +34,9 @@ extern const uint16_t fn_actions[];
|
|||||||
|
|
||||||
|
|
||||||
/* Common layout: ANSI+ISO
|
/* 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| =| /| *|
|
* | `| 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| |
|
* |Shif|\ | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
|
||||||
* |-----------------------------------------------------------| ,-----------. |-----------|Ent|
|
* |-----------------------------------------------------------| ,-----------. |-----------|Ent|
|
||||||
* |Ctrl |Opt |Cmd | Space | |Opt |Ctrl | |Lef|Dow|Rig| | 0| .| |
|
* |Ctrl |Opt |Cmd | Space |App |Opt |Ctrl | |Lef|Dow|Rig| | 0| .| |
|
||||||
* `-----------------------------------------------------------' `-----------' `---------------'
|
* `-----------------------------------------------------------' `-----------' `---------------'
|
||||||
*/
|
*/
|
||||||
#define KEYMAP( \
|
#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, \
|
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, \
|
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, \
|
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, \
|
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_##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 }, \
|
{ 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_##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_##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_##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_F17, KC_##K41, KC_##K42, 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_##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_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_##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_LANG2, KC_##K67 }, \
|
{ KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_HANJ, KC_##K67 }, \
|
||||||
{ KC_LANG1, KC_##K69, KC_F16, KC_##K6B, KC_NO, KC_##K6D, KC_APP, KC_##K6F }, \
|
{ 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_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 } \
|
{ KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_NO, KC_##K7F } \
|
||||||
}
|
}
|
||||||
|
@ -19,20 +19,20 @@
|
|||||||
*/
|
*/
|
||||||
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
[0] = KEYMAP(
|
[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,
|
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,
|
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,
|
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,
|
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(
|
[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,
|
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,
|
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,
|
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,
|
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
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,5 +23,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
void led_set(uint8_t usb_led)
|
void led_set(uint8_t usb_led)
|
||||||
{
|
{
|
||||||
adb_host_kbd_led(~usb_led);
|
adb_host_kbd_led(ADB_ADDR_KEYBOARD, ~usb_led);
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static bool has_media_keys = false;
|
||||||
static bool is_iso_layout = false;
|
static bool is_iso_layout = false;
|
||||||
static bool is_modified = false;
|
static bool is_modified = false;
|
||||||
static report_mouse_t mouse_report = {};
|
static report_mouse_t mouse_report = {};
|
||||||
@ -70,13 +71,26 @@ uint8_t matrix_cols(void)
|
|||||||
|
|
||||||
void matrix_init(void)
|
void matrix_init(void)
|
||||||
{
|
{
|
||||||
|
// LED on
|
||||||
|
DDRD |= (1<<6); PORTD |= (1<<6);
|
||||||
|
|
||||||
adb_host_init();
|
adb_host_init();
|
||||||
// wait for keyboard to boot up and receive command
|
// 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
|
// Determine ISO keyboard by handler id
|
||||||
// http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L815
|
// 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) {
|
switch (handler_id) {
|
||||||
case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
|
case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
|
||||||
case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
|
case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
|
||||||
@ -88,11 +102,27 @@ void matrix_init(void)
|
|||||||
break;
|
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
|
// Enable keyboard left/right modifier distinction
|
||||||
// Addr:Keyboard(0010), Cmd:Listen(10), Register3(11)
|
// Listen Register3
|
||||||
// upper byte: reserved bits 0000, device address 0010
|
// upper byte: reserved bits 0000, keyboard address 0010
|
||||||
// lower byte: device handler 00000011
|
// lower byte: device handler 00000011
|
||||||
adb_host_listen(0x2B,0x02,0x03);
|
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
|
// initialize matrix state: all keys off
|
||||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
|
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
|
||||||
@ -103,14 +133,8 @@ void matrix_init(void)
|
|||||||
//debug_mouse = true;
|
//debug_mouse = true;
|
||||||
print("debug enabled.\n");
|
print("debug enabled.\n");
|
||||||
|
|
||||||
// LED flash
|
// LED off
|
||||||
DDRD |= (1<<6); PORTD |= (1<<6);
|
|
||||||
_delay_ms(500);
|
|
||||||
DDRD |= (1<<6); PORTD &= ~(1<<6);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +216,50 @@ uint8_t matrix_scan(void)
|
|||||||
if ( codes == 0xFFFF )
|
if ( codes == 0xFFFF )
|
||||||
{
|
{
|
||||||
_delay_ms(12); // delay for preventing overload of poor ADB keyboard controller
|
_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;
|
key0 = codes>>8;
|
||||||
key1 = codes&0xFF;
|
key1 = codes&0xFF;
|
||||||
|
Reference in New Issue
Block a user