diff --git a/keyboards/ymdk/sp64/config.h b/keyboards/ymdk/sp64/config.h
new file mode 100644
index 0000000000..fc3e2d7dc2
--- /dev/null
+++ b/keyboards/ymdk/sp64/config.h
@@ -0,0 +1,45 @@
+/*
+Copyright 2019 Neil Kettle
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+#define VENDOR_ID 0x594D
+#define PRODUCT_ID 0x5364
+#define DEVICE_VER 0x0200
+#define MANUFACTURER YMDK
+#define PRODUCT SP64
+#define DESCRIPTION YMDK Split 64
+
+#define MATRIX_ROWS 6
+#define MATRIX_COLS 15
+
+#define RIGHT_HALF
+
+/* disable these deprecated features by default */
+#define NO_ACTION_MACRO
+#define NO_ACTION_FUNCTION
+
+/* RGB underglow */
+#define RGBLED_NUM 12
+#define RGBLIGHT_HUE_STEP 8
+#define RGBLIGHT_SAT_STEP 8
+#define RGBLIGHT_VAL_STEP 8
+#define RGBLIGHT_LIMIT_VAL 250 /* The maximum brightness level */
+#define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
+#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/ymdk/sp64/info.json b/keyboards/ymdk/sp64/info.json
new file mode 100644
index 0000000000..798124d848
--- /dev/null
+++ b/keyboards/ymdk/sp64/info.json
@@ -0,0 +1,79 @@
+{
+ "keyboard_name": "YMDK_SP64",
+ "url": "",
+ "maintainer": "walston",
+ "width": 16,
+ "height": 5,
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"label":"~", "x":0, "y":0},
+ {"label":"!", "x":1, "y":0},
+ {"label":"@", "x":2, "y":0},
+ {"label":"#", "x":3, "y":0},
+ {"label":"$", "x":4, "y":0},
+ {"label":"%", "x":5, "y":0},
+ {"label":"^", "x":6, "y":0},
+ {"label":"&", "x":8, "y":0},
+ {"label":"*", "x":9, "y":0},
+ {"label":"(", "x":10, "y":0},
+ {"label":")", "x":11, "y":0},
+ {"label":"_", "x":12, "y":0},
+ {"label":"+", "x":13, "y":0},
+ {"label":"Backspace", "x":14, "y":0, "w":2},
+ {"label":"Tab", "x":0, "y":1, "w":1.5},
+ {"label":"Q", "x":1.5, "y":1},
+ {"label":"W", "x":2.5, "y":1},
+ {"label":"E", "x":3.5, "y":1},
+ {"label":"R", "x":4.5, "y":1},
+ {"label":"T", "x":5.5, "y":1},
+ {"label":"Y", "x":7.5, "y":1},
+ {"label":"U", "x":8.5, "y":1},
+ {"label":"I", "x":9.5, "y":1},
+ {"label":"O", "x":10.5, "y":1},
+ {"label":"P", "x":11.5, "y":1},
+ {"label":"{ ", "x":12.5, "y":1},
+ {"label":"}", "x":13.5, "y":1},
+ {"label":"|", "x":14.5, "y":1, "w":1.5},
+ {"label":"Caps Lock", "x":0, "y":2, "w":1.75},
+ {"label":"A", "x":1.75, "y":2},
+ {"label":"S", "x":2.75, "y":2},
+ {"label":"D", "x":3.75, "y":2},
+ {"label":"F", "x":4.75, "y":2},
+ {"label":"G", "x":5.75, "y":2},
+ {"label":"H", "x":7.75, "y":2},
+ {"label":"J", "x":8.75, "y":2},
+ {"label":"K", "x":9.75, "y":2},
+ {"label":"L", "x":10.75, "y":2},
+ {"label":":", "x":11.75, "y":2},
+ {"label":"\"", "x":12.75, "y":2},
+ {"label":"Enter", "x":13.75, "y":2, "w":2.25},
+ {"label":"Shift", "x":0, "y":3, "w":2},
+ {"label":"Z", "x":2, "y":3},
+ {"label":"X", "x":3, "y":3},
+ {"label":"C", "x":4, "y":3},
+ {"label":"V", "x":5, "y":3},
+ {"label":"B", "x":6, "y":3},
+ {"label":"N", "x":8, "y":3},
+ {"label":"M", "x":9, "y":3},
+ {"label":"<", "x":10, "y":3},
+ {"label":">", "x":11, "y":3},
+ {"label":"?", "x":12, "y":3},
+ {"label":"Shift", "x":13, "y":3},
+ {"label":"Up", "x":14, "y":3},
+ {"label":"F3", "x":15, "y":3},
+ {"label":"Ctrl", "x":0, "y":4, "w":1.25},
+ {"label":"Win", "x":1.25, "y":4},
+ {"label":"Alt", "x":2.25, "y":4, "w":1.25},
+ {"label":"Space", "x":3.5, "y":4, "w":2.25},
+ {"label":"Fn", "x":5.75, "y":4},
+ {"label":"Space", "x":7.75, "y":4, "w":2.75},
+ {"label":"Alt", "x":10.5, "y":4, "w":1.25},
+ {"label":"Win", "x":11.75, "y":4, "w":1.25},
+ {"label":"Left", "x":13, "y":4},
+ {"label":"Down", "x":14, "y":4},
+ {"label":"Right", "x":15, "y":4}
+ ]
+ }
+ }
+}
diff --git a/keyboards/ymdk/sp64/keymaps/daed/keymap.c b/keyboards/ymdk/sp64/keymaps/daed/keymap.c
new file mode 100644
index 0000000000..7174c108b3
--- /dev/null
+++ b/keyboards/ymdk/sp64/keymaps/daed/keymap.c
@@ -0,0 +1,140 @@
+#include QMK_KEYBOARD_H
+
+enum layer_names {
+ _BASE,
+ _GAMER,
+ _FN,
+ _RAISE,
+ _MODE,
+ _GACROS,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+/* Keymap 0: Basic layer
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ Esc │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ │ 7 │ 8 │ 9 │ 0 │ - │ = │ BkSp │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ Tab │ Q │ W │ E │ R │ T │ │ Y │ U │ I │ O │ P │ [ │ ] │ \ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ Ctrl │ A │ S │ D │ F │ G │ │ H │ J │ K │ L │ ; │ ' │ Enter │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ LShift │ Z │ X │ C │ V │ B │ │ N │ M │ < │ > │ ? │ Sft │ Up │ _MO │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ _FN │ Win │ Alt │ │ _RA │ │ │ Alt │ Win │ Lft │ Dwn │ Rgt │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_BASE] = LAYOUT(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, KC_EQUAL, KC_BSPACE,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRACKET, KC_RBRACKET, KC_BSLS,
+ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCOLON, KC_QUOTE, KC_ENTER,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, MO(_MODE),
+ MO(_FN), KC_LGUI, KC_LALT, KC_SPACE, MO(_RAISE), KC_SPACE, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RIGHT
+ ),
+/* Keymap 1: Gamer layer
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ Esc │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ │ 7 │ 8 │ 9 │ 0 │ - │ = │ BkSp │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ Tab │ Q │ W │ E │ R │ T │ │ Y │ U │ I │ O │ P │ [ │ ] │ \ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ Ctrl │ A │ S │ D │ F │ G │ │ H │ J │ K │ L │ ; │ ' │ Enter │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ LShift │ Z │ X │ C │ V │ B │ │ N │ M │ < │ > │ ? │ Sft │ Up │ _MO │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ _FN │ F13 │ Alt │ │ _GA │ │ │ Alt │ Win │ Lft │ Dwn │ Rgt │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_GAMER] = LAYOUT(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, KC_EQUAL, KC_BSPACE,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRACKET, KC_RBRACKET, KC_BSLS,
+ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCOLON, KC_QUOTE, KC_ENTER,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, MO(_MODE),
+ MO(_FN), KC_F13, KC_LALT, KC_SPACE, MO(_GACROS), KC_SPACE, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RIGHT
+ ),
+
+/* Keymap 2: Function
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ ` │ F1 │ F2 │ F3 │ F4 │ F5 │ F6 │ │ F7 │ F8 │ F9 │ F10 │ F11 │ F12 │ │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ │ │ │ │ │ │ │Left │ Up │Down │Right│ │ │ │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_FN] = LAYOUT(
+ KC_GRAVE, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ KC_CAPS, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PGUP, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END
+ ),
+/* Keymap 3: Raise / Quality of life
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ ` │ F1 │ F2 │ F3 │ F4 │ F5 │ F6 │ │ F7 │ F8 │ F9 │ F10 │ F11 │ F12 │ │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ │ │ │ │ │ │ │Left │ Up │Down │Right│ │ │ │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_RAISE] = LAYOUT(
+ KC_GRAVE, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ KC_CAPS, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PGUP, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END
+ ),
+/* Keymap 4: Mode switching
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ ` │ F1 │ F2 │ F3 │ F4 │ F5 │ F6 │ │ F7 │ F8 │ F9 │ F10 │ F11 │ F12 │ │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ RGB 0/1│RGBM-│RGBB+│RGBM+│ │ │ │ │ │ │ │ │ │ │ Reset │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ │RGBS-│RGBB-│RGBS+│ │ │ │Left │ Up │Down │Right│ │ │ │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ GAME| BASE│ │ │ │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_MODE] = LAYOUT(
+ KC_GRAVE, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______,
+ RGB_TOG, RGB_RMOD, RGB_VAI, RGB_MOD, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET,
+ _______, RGB_SPD, RGB_VAD, RGB_SPI, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, TO(_GAMER), TO(_BASE), _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+/* Keymap 5: Gaming macros
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ ` │ F1 │ F2 │ F3 │ F4 │ F5 │ F6 │ │ F7 │ F8 │ F9 │ F10 │ F11 │ F12 │ │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ │ │ PUSH│ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ │ │ FALL│ │ │ │ │Left │ Up │Down │Right│ │ │ │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ │ │ CAP │ │ │ │ │ │ │ │ GAME| BASE│ │ │ │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_GACROS] = LAYOUT(
+ KC_GRAVE, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, TO(_GAMER), TO(_BASE), _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+};
diff --git a/keyboards/ymdk/sp64/keymaps/default/keymap.c b/keyboards/ymdk/sp64/keymaps/default/keymap.c
new file mode 100644
index 0000000000..e988d6e91b
--- /dev/null
+++ b/keyboards/ymdk/sp64/keymaps/default/keymap.c
@@ -0,0 +1,74 @@
+#include QMK_KEYBOARD_H
+
+enum layer_names {
+ BASE, // default layer
+ _FN, // function layer
+ _FX // media keys
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+/* Keymap 0: Basic layer
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ Esc │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ │ 7 │ 8 │ 9 │ 0 │ - │ = │ BkSp │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ Tab │ Q │ W │ E │ R │ T │ │ Y │ U │ I │ O │ P │ [ │ ] │ \ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ Caps │ A │ S │ D │ F │ G │ │ H │ J │ K │ L │ ; │ ' │ Enter │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ LShift │ Z │ X │ C │ V │ B │ │ N │ M │ < │ > │ ? │ Sft │ Up │ Fn │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ Ctrl │ Win │ Alt │ │ Fn │ │ │ Alt │ Win │ Lft │ Dwn │ Rgt │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[BASE] = LAYOUT(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, KC_EQUAL, KC_BSPACE,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRACKET, KC_RBRACKET, KC_BSLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCOLON, KC_QUOTE, KC_ENTER,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_F3,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPACE, MO(_FN), KC_SPACE, KC_RALT, KC_RGUI, KC_LEFT, KC_DOWN, KC_RIGHT
+ ),
+/* Function
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ │ F1 │ F2 │ F3 │ F4 │ F5 │ F6 │ │ F7 │ F8 │ F9 │ F10 │ F11 │ F12 │ │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_FN] = LAYOUT(
+ _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+/* Media
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_FX] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+};
+
diff --git a/keyboards/ymdk/sp64/keymaps/walston/keymap.c b/keyboards/ymdk/sp64/keymaps/walston/keymap.c
new file mode 100644
index 0000000000..ada3073fb9
--- /dev/null
+++ b/keyboards/ymdk/sp64/keymaps/walston/keymap.c
@@ -0,0 +1,94 @@
+#include QMK_KEYBOARD_H
+enum layer_names {
+ BASE, // default layer
+ _FUN, // function layer
+ _NUMPAD, // num-pad
+ _MEDIA // media keys
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+/* Keymap 0: Basic layer
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ │ 7 │ 8 │ 9 │ 0 │ - │ = │ BkSp │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ Tab │ Q │ W │ E │ R │ T │ │ Y │ U │ I │ O │ P │ [ │ ] │ \ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ Ctrl │ A │ S │ D │ F │ G │ │ H │ J │ K │ L │ ; │ ' │ Enter │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ LShift │ Z │ X │ C │ V │ B │ │ N │ M │ < │ > │ ? │ Sft │ Up │_MED │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ _NUM │_MED │ Alt │ Cmd │ Spc │ │ Space │ Cmd │ Alt │ Lft │ Dwn │ Rgt │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[BASE] = LAYOUT(
+ MT(RESET, KC_GRAVE), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, KC_EQUAL, KC_BSPACE,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRACKET, KC_RBRACKET, KC_BSLS,
+ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCOLON, KC_QUOTE, KC_ENTER,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, OSL(_MEDIA),
+ LT(_NUMPAD, KC_CAPS), TT(_MEDIA), KC_LALT, KC_LGUI, LT(_FUN, KC_SPACE), KC_SPACE, KC_RGUI, KC_RALT, KC_LEFT, KC_DOWN, KC_RIGHT
+ ),
+/* Keymap 1: Function Layer / Vim Arrows
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ Esc │ F1 │ F2 │ F3 │ F4 │ F5 │ F6 │ │ F7 │ F8 │ F9 │ F10 │ F11 │ F12 │ │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ │ │ │ │ │ │ │ │Left │ Up │Down │Right│ │ │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_FUN] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, KC_LEFT, KC_UP, KC_DOWN, KC_RIGHT, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+/* Keymap 2: NumPad
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ │ │ │ │ │ │ │ │ 7 │ 8 │ 9 │ │ Vol-│ Vol+│ Mute │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ │ │ │ │ │ │ │ │ 4 │ 5 │ 6 │ │ |<< │ >>| │ >|| │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ │ │ │ │ │ │ │ │ 1 │ 2 │ 3 │ │ │ │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ │ │ │ │ │ │ │ │ 0 │ │ │ │ │ │ │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_NUMPAD] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, KC_P7, KC_P8, KC_P9, _______, KC_VOLD, KC_VOLU, KC_MUTE,
+ _______, _______, _______, _______, _______, _______, _______, KC_P4, KC_P5, KC_P6, _______, KC_MPRV, KC_MNXT, KC_MPLY,
+ _______, _______, _______, _______, _______, _______, _______, KC_P1, KC_P2, KC_P3, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, KC_P0, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ ),
+/* Keymap 3: Media
+ *
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ │ │ │ Backlight │ │ │ │ │ │ │ │ │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+[_MEDIA] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, RGB_TOG, _______, _______, _______, _______, _______, _______, _______
+ ),
+};
diff --git a/keyboards/ymdk/sp64/keymaps/walston/rules.mk b/keyboards/ymdk/sp64/keymaps/walston/rules.mk
new file mode 100644
index 0000000000..a6c5cfa18a
--- /dev/null
+++ b/keyboards/ymdk/sp64/keymaps/walston/rules.mk
@@ -0,0 +1 @@
+COMMAND_ENABLE = no
diff --git a/keyboards/ymdk/sp64/matrix.c b/keyboards/ymdk/sp64/matrix.c
new file mode 100644
index 0000000000..8dd2bb8d76
--- /dev/null
+++ b/keyboards/ymdk/sp64/matrix.c
@@ -0,0 +1,169 @@
+/*
+Copyright 2013 Oleg Kostyuk
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "matrix.h"
+#include
+#include
+#include
+#include "wait.h"
+#include "action_layer.h"
+#include "print.h"
+#include "debug.h"
+#include "util.h"
+#include "sp64.h"
+#include "debounce.h"
+
+/* matrix state(1:on, 0:off) */
+static matrix_row_t matrix[MATRIX_ROWS];
+
+// Debouncing: store for each key the number of scans until it's eligible to
+// change. When scanning the matrix, ignore any changes in keys that have
+// already changed in the last DEBOUNCE scans.
+static matrix_row_t matrix_debouncing[MATRIX_ROWS];
+
+static void matrix_select_row(uint8_t row);
+
+#ifdef RIGHT_HALF
+static uint8_t mcp23018_reset_loop = 0;
+#endif
+
+void matrix_init(void)
+{
+ // all outputs for rows high
+ DDRB = 0xFF;
+ PORTB = 0xFF;
+ // all inputs for columns
+ DDRA = 0x00;
+ DDRC &= ~(0x111111<<2);
+ DDRD &= ~(1<= 1300) {
+ // since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans
+ // this will be approx bit more frequent than once per second
+ print("trying to reset mcp23018\n");
+ mcp23018_status = init_mcp23018();
+ if (mcp23018_status) {
+ print("left side not responding\n");
+ } else {
+ print("left side attached\n");
+ }
+ }
+ }
+#endif
+ bool changed = false;
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++)
+ {
+ matrix_row_t cols;
+
+ matrix_select_row(row);
+#ifndef RIGHT_HALF
+ _delay_us(5);
+#endif
+
+ cols = (
+ // cols 0..7, PORTA 0 -> 7
+ (~PINA) & 0xFF
+ );
+
+#ifdef RIGHT_HALF
+ uint8_t data = 0x7F;
+ // Receive the columns from right half
+ i2c_receive(I2C_ADDR_WRITE, &data, 1, MCP23018_I2C_TIMEOUT);
+ cols |= ((~(data) & 0x7F) << 7);
+#endif
+
+ if (matrix_debouncing[row] != cols) {
+ matrix_debouncing[row] = cols;
+ //debouncing = DEBOUNCE;
+ changed = true;
+ }
+ }
+
+ debounce(matrix_debouncing, matrix, MATRIX_ROWS, changed);
+
+ matrix_scan_quantum();
+
+#ifdef DEBUG_MATRIX
+ for (uint8_t c = 0; c < MATRIX_COLS; c++)
+ for (uint8_t r = 0; r < MATRIX_ROWS; r++)
+ if (matrix_is_on(r, c)) xprintf("r:%d c:%d \n", r, c);
+#endif
+
+ return (uint8_t)changed;
+}
+
+inline
+matrix_row_t matrix_get_row(uint8_t row)
+{
+ return matrix[row];
+}
+
+void matrix_print(void)
+{
+ print("\nr/c 0123456789ABCDEF\n");
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ phex(row); print(": ");
+ pbin_reverse16(matrix_get_row(row));
+ print("\n");
+ }
+}
+
+uint8_t matrix_key_count(void)
+{
+ uint8_t count = 0;
+ for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+ count += bitpop16(matrix[i]);
+ }
+ return count;
+}
+
+static void matrix_select_row(uint8_t row)
+{
+#ifdef RIGHT_HALF
+ uint8_t txdata[3];
+
+ //Set the remote row on port A
+ txdata[0] = GPIOA;
+ txdata[1] = 0xFF & ~(1<
.
+ */
+
+#include "sp64.h"
+
+#ifdef RIGHT_HALF
+bool i2c_initialized = 0;
+i2c_status_t mcp23018_status = I2C_STATUS_ERROR;
+
+uint8_t init_mcp23018(void)
+{
+ uint8_t data[3];
+ mcp23018_status = I2C_STATUS_ERROR;
+
+ // I2C subsystem
+ if (i2c_initialized == 0) {
+ i2c_init(); // on pins D(1,0)
+ i2c_initialized = true;
+ _delay_ms(1000);
+ }
+
+ // set pin direction
+ // - unused : input : 1
+ // - input : input : 1
+ // - driving : output :
+ data[0] = IODIRA;
+ data[1] = 0b00000000;
+ data[2] = 0b11111111;
+ mcp23018_status = i2c_transmit(I2C_ADDR_WRITE, (uint8_t *)data, 3, MCP23018_I2C_TIMEOUT);
+ if (mcp23018_status != I2C_STATUS_SUCCESS)
+ goto out;
+
+ // set pull-up
+ // - unused : on : 1
+ // - input : on : 1
+ // - driving : off : 0
+ data[0] = GPPUA;
+ data[1] = 0b00000000;
+ data[2] = 0b11111111;
+ mcp23018_status = i2c_transmit(I2C_ADDR_WRITE, (uint8_t *)data, 3, MCP23018_I2C_TIMEOUT);
+ if (mcp23018_status != I2C_STATUS_SUCCESS)
+ goto out;
+
+ // set logical value (doesn't matter on inputs)
+ // - unused : hi-Z : 1
+ // - input : hi-Z : 1
+ // - driving : hi-Z : 1
+ data[0] = OLATA;
+ data[1] = 0b11111111;
+ data[2] = 0b11111111;
+ mcp23018_status = i2c_transmit(I2C_ADDR_WRITE, (uint8_t *)data, 3, MCP23018_I2C_TIMEOUT);
+
+out:
+ return (mcp23018_status);
+}
+#endif
+
+// Optional override functions below.
+// You can leave any or all of these undefined.
+// These are only required if you want to perform custom actions.
+
+__attribute__ ((weak))
+void matrix_init_user(void) {}
+
+void matrix_init_kb(void) {
+ // put your keyboard start-up code here
+ // runs once when the firmware starts up
+
+ matrix_init_user();
+}
+
+__attribute__ ((weak))
+void matrix_scan_user(void) {}
+
+void matrix_scan_kb(void) {
+ // put your looping keyboard code here
+ // runs every cycle (a lot)
+
+ matrix_scan_user();
+}
diff --git a/keyboards/ymdk/sp64/sp64.h b/keyboards/ymdk/sp64/sp64.h
new file mode 100644
index 0000000000..63620f0c3c
--- /dev/null
+++ b/keyboards/ymdk/sp64/sp64.h
@@ -0,0 +1,84 @@
+/* Copyright 2019 Neil Kettle
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#include "quantum.h"
+
+#ifdef RIGHT_HALF
+# include
+# include "i2c_master.h"
+
+// I2C aliases and register addresses (see "mcp23018.md")
+# define I2C_ADDR 0b0100000
+# define I2C_ADDR_WRITE ( (I2C_ADDR<<1) | I2C_WRITE )
+# define I2C_ADDR_READ ( (I2C_ADDR<<1) | I2C_READ )
+# define IODIRA 0x00 // i/o direction register
+# define IODIRB 0x01
+# define GPPUA 0x0C // GPIO pull-up resistor register
+# define GPPUB 0x0D
+# define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT)
+# define GPIOB 0x13
+# define OLATA 0x14 // output latch register
+# define OLATB 0x15
+
+extern i2c_status_t mcp23018_status;
+# define MCP23018_I2C_TIMEOUT 100
+
+uint8_t init_mcp23018(void);
+#endif
+
+#define ___ KC_NO
+#define XXX KC_NO
+
+/* This is a shortcut to help you visually see your layout.
+ *
+ * The first section contains all of the arguments representing the physical
+ * layout of the board and position of the keys.
+ *
+ * The second converts the arguments into a two-dimensional array which
+ * represents the switch matrix.
+ *
+ * LEFT HAND RIGHT HAND
+ * ┌-----┬-----┬-----┬-----┬-----┬-----┬-----┐ ┌-----┬-----┬-----┬-----┬-----┬-----┬----------┐
+ * │ L00 │ L01 │ L02 │ L03 │ L04 │ L05 │ L06 │ │ R07 │ R08 │ R09 │ R0A │ R0B │ R0C │ R0D │
+ * ├-----┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┘ ┌--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬--┴--┬-------┤
+ * │ L10 │ L11 │ L12 │ L13 │ L14 │ L15 │ │ R16 │ R17 │ R18 │ R19 │ R1A │ R1B │ R1C │ R1D │
+ * ├--------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴-------┤
+ * │ L20 │ L21 │ L22 │ L23 │ L24 │ L25 │ │ R26 │ R27 │ R28 │ R29 │ R2A │ R2B │ R2C │
+ * ├---------┴┬----┴┬----┴┬----┴┬----┴┬----┴┐ └┬----┴┬----┴┬----┴┬----┴┬----┴┬----┴┬-----┬-----┤
+ * │ L30 │ L31 │ L32 │ L33 │ L34 │ L35 │ │ R36 │ R37 │ R38 │ R39 │ R3A │ R3B │ R3C │ R3D │
+ * ├------┬---┴-┬---┴--┬--┴-----┴----┬┴----┬┘ ┌┴-----┴-----┴--┬--┴----┬┴-----┼-----┼-----┼-----┤
+ * │ L40 │ L41 │ L42 │ L43 │ L45 │ │ R46 │ R48 │ R4A │ R4B │ R4C │ R4D │
+ * └------┴-----┴------┴-------------┴-----┘ └---------------┴-------┴------┴-----┴-----┴-----┘
+ */
+#define LAYOUT( \
+ L00, L01, L02, L03, L04, L05, L06, R07, R08, R09, R0A, R0B, R0C, R0D, \
+ L10, L11, L12, L13, L14, L15, R16, R17, R18, R19, R1A, R1B, R1C, R1D, \
+ L20, L21, L22, L23, L24, L25, R26, R27, R28, R29, R2A, R2B, R2C, \
+ L30, L31, L32, L33, L34, L35, R36, R37, R38, R39, R3A, R3B, R3C, R3D, \
+ L40, L41, L42, L43, L45, R46, R48, R4A, R4B, R4C, R4D \
+ ) \
+ /* matrix positions */ \
+ { \
+ { ___, ___, ___, ___, ___, ___, ___, R46, R48, R4A, R4B, R4C, R4D, R3D }, \
+ { L40, L41, L42, L43, L45, L06, ___, R36, R37, R38, R39, R3A, R3B, R3C }, \
+ { L30, L31, L32, L33, L34, L35, ___, R26, R27, R28, R29, R2A, R2B, R2C }, \
+ { L20, L21, L22, L23, L24, L25, ___, R17, R18, R19, R1A, R1B, R1C, R1D }, \
+ { L10, L11, L12, L13, L14, L15, ___, R07, R08, R09, R0A, R0B, R0C, R0D }, \
+ { L00, L01, L02, L03, L04, L05, ___, R16, ___, ___, ___, ___, ___, ___ } \
+ }
+