diff --git a/.clangd b/.clangd
index 6133ae7229d..63dadd7e7c1 100644
--- a/.clangd
+++ b/.clangd
@@ -1,4 +1,4 @@
CompileFlags:
Add: [-Wno-unknown-attributes, -Wno-maybe-uninitialized, -Wno-unknown-warning-option]
- Remove: [-W*, -mmcu=*, -mcpu=*, -mfpu=*, -mfloat-abi=*, -mno-unaligned-access, -mno-thumb-interwork, -mcall-prologues]
+ Remove: [-W*, -mmcu=*, -mcpu=*, -mfpu=*, -mfloat-abi=*, -mno-unaligned-access, -mno-thumb-interwork, -mcall-prologues, -D__has_include*]
Compiler: clang
diff --git a/data/schemas/community_module.jsonschema b/data/schemas/community_module.jsonschema
index a3474476dff..3cdb6d6a422 100644
--- a/data/schemas/community_module.jsonschema
+++ b/data/schemas/community_module.jsonschema
@@ -3,7 +3,7 @@
"$id": "qmk.community_module.v1",
"title": "Community Module Information",
"type": "object",
- "required": ["module_name", "maintainer"]
+ "required": ["module_name", "maintainer"],
"properties": {
"module_name": {"$ref": "qmk.definitions.v1#/text_identifier"},
"maintainer": {"$ref": "qmk.definitions.v1#/text_identifier"},
@@ -12,6 +12,6 @@
"format": "uri"
},
"keycodes": {"$ref": "qmk.definitions.v1#/keycode_decl_array"},
- "features": {"$ref": "qmk.keyboard.v1#/definitions/features_config"},
+ "features": {"$ref": "qmk.keyboard.v1#/definitions/features_config"}
}
}
diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema
index 9b63f62d451..92a17e1ef89 100644
--- a/data/schemas/keyboard.jsonschema
+++ b/data/schemas/keyboard.jsonschema
@@ -30,12 +30,12 @@
"properties": {
"pins": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}
}
- }
+ },
"features_config": {
"$ref": "qmk.definitions.v1#/boolean_array",
"propertyNames": {"$ref": "qmk.definitions.v1#/snake_case"},
"not": {"required": ["lto"]}
- },
+ }
},
"type": "object",
"not": {"required": ["vendorId", "productId"]}, // reject via keys...
@@ -354,7 +354,7 @@
"axis_resolution": {"$ref": "qmk.definitions.v1#/unsigned_int"},
"axes": {
"type": "object",
- "propertyNames": {"enum": ["x", "y", "z", "rx", "ry", "rz"]}
+ "propertyNames": {"enum": ["x", "y", "z", "rx", "ry", "rz"]},
"additionalProperties": {
"oneOf": [
{
diff --git a/data/schemas/user_repo_v0.jsonschema b/data/schemas/user_repo_v0.jsonschema
index b18ac504284..58d955abe27 100644
--- a/data/schemas/user_repo_v0.jsonschema
+++ b/data/schemas/user_repo_v0.jsonschema
@@ -8,7 +8,7 @@
],
"properties": {
"userspace_version": {
- "type": "string",
- },
+ "type": "string"
+ }
}
}
diff --git a/data/schemas/user_repo_v1.jsonschema b/data/schemas/user_repo_v1.jsonschema
index 69a59bce007..88b50e8a726 100644
--- a/data/schemas/user_repo_v1.jsonschema
+++ b/data/schemas/user_repo_v1.jsonschema
@@ -9,7 +9,7 @@
{"$ref": "qmk.definitions.v1#/keyboard_keymap_tuple"},
{"$ref": "qmk.definitions.v1#/json_file_path"}
]
- },
+ }
},
"required": [
"userspace_version",
diff --git a/data/schemas/user_repo_v1_1.jsonschema b/data/schemas/user_repo_v1_1.jsonschema
index 5a7ccce0633..173d8d26d63 100644
--- a/data/schemas/user_repo_v1_1.jsonschema
+++ b/data/schemas/user_repo_v1_1.jsonschema
@@ -10,7 +10,7 @@
{"$ref": "qmk.definitions.v1#/keyboard_keymap_env"},
{"$ref": "qmk.definitions.v1#/json_file_path"}
]
- },
+ }
},
"required": [
"userspace_version",
diff --git a/docs/config_options.md b/docs/config_options.md
index 90a708dd99c..e75a5b2f7ec 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -401,6 +401,7 @@ This is a [make](https://www.gnu.org/software/make/manual/make.html) file that i
* `atmel-dfu`
* `lufa-dfu`
* `qmk-dfu`
+ * `qmk-hid`
* `halfkay`
* `caterina`
* `bootloadhid`
diff --git a/docs/features/led_matrix.md b/docs/features/led_matrix.md
index 756cc11e2be..113b13f03b6 100644
--- a/docs/features/led_matrix.md
+++ b/docs/features/led_matrix.md
@@ -227,6 +227,8 @@ For inspiration and examples, check out the built-in effects under `quantum/led_
#define LED_MATRIX_DEFAULT_MODE LED_MATRIX_SOLID // Sets the default mode, if none has been set
#define LED_MATRIX_DEFAULT_VAL LED_MATRIX_MAXIMUM_BRIGHTNESS // Sets the default brightness value, if none has been set
#define LED_MATRIX_DEFAULT_SPD 127 // Sets the default animation speed, if none has been set
+#define LED_MATRIX_VAL_STEP 8 // The value by which to increment the brightness per adjustment action
+#define LED_MATRIX_SPD_STEP 16 // The value by which to increment the animation speed per adjustment action
#define LED_MATRIX_DEFAULT_FLAGS LED_FLAG_ALL // Sets the default LED flags, if none has been set
#define LED_MATRIX_SPLIT { X, Y } // (Optional) For split keyboards, the number of LEDs connected on each half. X = left, Y = Right.
// If reactive effects are enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR
diff --git a/docs/features/rgb_matrix.md b/docs/features/rgb_matrix.md
index 0e53ce9c35a..a22f931f1be 100644
--- a/docs/features/rgb_matrix.md
+++ b/docs/features/rgb_matrix.md
@@ -378,6 +378,10 @@ These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master
#define RGB_MATRIX_DEFAULT_SAT 255 // Sets the default saturation value, if none has been set
#define RGB_MATRIX_DEFAULT_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS // Sets the default brightness value, if none has been set
#define RGB_MATRIX_DEFAULT_SPD 127 // Sets the default animation speed, if none has been set
+#define RGB_MATRIX_HUE_STEP 8 // The value by which to increment the hue per adjustment action
+#define RGB_MATRIX_SAT_STEP 16 // The value by which to increment the saturation per adjustment action
+#define RGB_MATRIX_VAL_STEP 16 // The value by which to increment the brightness per adjustment action
+#define RGB_MATRIX_SPD_STEP 16 // The value by which to increment the animation speed per adjustment action
#define RGB_MATRIX_DEFAULT_FLAGS LED_FLAG_ALL // Sets the default LED flags, if none has been set
#define RGB_MATRIX_SPLIT { X, Y } // (Optional) For split keyboards, the number of LEDs connected on each half. X = left, Y = Right.
// If reactive effects are enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR
diff --git a/docs/features/rgblight.md b/docs/features/rgblight.md
index 4322fe796e7..43e3781f8d4 100644
--- a/docs/features/rgblight.md
+++ b/docs/features/rgblight.md
@@ -97,9 +97,9 @@ Your RGB lighting can be configured by placing these `#define`s in your `config.
|Define |Default |Description |
|---------------------------|----------------------------|---------------------------------------------------------------------------------------------------------------------------|
-|`RGBLIGHT_HUE_STEP` |`8` |The number of steps to cycle through the hue by |
-|`RGBLIGHT_SAT_STEP` |`17` |The number of steps to increment the saturation by |
-|`RGBLIGHT_VAL_STEP` |`17` |The number of steps to increment the brightness by |
+|`RGBLIGHT_HUE_STEP` |`8` |The value by which to increment the hue per adjustment action |
+|`RGBLIGHT_SAT_STEP` |`17` |The value by which to increment the saturation per adjustment action |
+|`RGBLIGHT_VAL_STEP` |`17` |The value by which to increment the brightness per adjustment action |
|`RGBLIGHT_LIMIT_VAL` |`255` |The maximum brightness level |
|`RGBLIGHT_SLEEP` |*Not defined* |If defined, the RGB lighting will be switched off when the host goes to sleep |
|`RGBLIGHT_SPLIT` |*Not defined* |If defined, synchronization functionality for split keyboards is added |
diff --git a/docs/hand_wire.md b/docs/hand_wire.md
index 9aeee7512dc..be21cf2cc4f 100644
--- a/docs/hand_wire.md
+++ b/docs/hand_wire.md
@@ -231,7 +231,7 @@ Once you have confirmed that the keyboard is working, if you have used a seperat
If you found this fullfilling you could experiment by adding additional features such as [in switch LEDs](https://geekhack.org/index.php?topic=94258.0), [in switch RGB](https://www.reddit.com/r/MechanicalKeyboards/comments/5s1l5u/photoskeyboard_science_i_made_a_handwired_rgb/), [RGB underglow](https://medium.com/@DavidNZ/hand-wired-custom-keyboard-cdd14429c7b3#.7a1ovebsk) or even an [OLED display!](https://www.reddit.com/r/olkb/comments/5zy7og/adding_ssd1306_oled_display_to_your_build/)
-There are a lot of possibilities inside the firmware - explore [docs.qmk.fm](https://docs.qmk.fm) for a full feature list, and dive into the different keyboards to see how people use all of them. You can always stop by [the OLKB subreddit](https://reddit.com/r/olkb) or [QMK Discord](https://discord.gg/qmk) for help!
+There are a lot of possibilities inside the firmware - explore [the documentation](/) for a full feature list, and dive into the different keyboards to see how people use all of them. You can always stop by [the OLKB subreddit](https://reddit.com/r/olkb) or [QMK Discord](https://discord.gg/qmk) for help!
## Links to Other Guides
diff --git a/docs/license_violations.md b/docs/license_violations.md
index cf7850effc1..0bc62102ed3 100644
--- a/docs/license_violations.md
+++ b/docs/license_violations.md
@@ -85,7 +85,7 @@ Reusing the `VID` and `PID` for multiple boards (such as for two variants, wired
If there is sufficient ambiguity about a board, supporting evidence will need to be presented to the QMK team. This may include impartial third parties who can demonstrate a board's existence and can confirm its feature set, such as well-known content producers; popular review sites or notable video creators may be leveraged. If such evidence is unavailable, as a last resort the vendor may be required to ship a fully functional board in full retail packaging to QMK maintainers for verification. Engineering samples will not be accepted, as one-off boards have been deceptively used in the past.
-PRs submitted to upstream QMK should not expect an instant merge just because source code has been provided -- code from OEMs has historically been of a quality lower than QMK standards, so as per the [PR checklist](https://docs.qmk.fm/pr_checklist) submitters should make the changes as small as possible and be prepared to change their implementation.
+PRs submitted to upstream QMK should not expect an instant merge just because source code has been provided -- code from OEMs has historically been of a quality lower than QMK standards, so as per the [PR checklist](pr_checklist) submitters should make the changes as small as possible and be prepared to change their implementation.
## Detection
diff --git a/docs/reference_info_json.md b/docs/reference_info_json.md
index 29b999c32e8..0f8f680b551 100644
--- a/docs/reference_info_json.md
+++ b/docs/reference_info_json.md
@@ -413,7 +413,7 @@ Configures the [LED Matrix](features/led_matrix) feature.
* Default: `16`
* `led_process_limit` Number
* Limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness).
- * Default: `led_count / 5`
+ * Default: `(led_count + 4) / 5`
* `max_brightness` Number
* The maximum value which brightness is scaled to, from 0 to 255.
* Default: `255`
@@ -424,7 +424,7 @@ Configures the [LED Matrix](features/led_matrix) feature.
* Turn off the LEDs when the host goes to sleep.
* Default: `false`
* `speed_steps` Number
- * The number of speed adjustment steps.
+ * The value by which to increment the speed.
* Default: `16`
* `split_count` Array: Number
* For split keyboards, the number of LEDs on each half.
@@ -433,7 +433,7 @@ Configures the [LED Matrix](features/led_matrix) feature.
* The LED activity timeout in milliseconds.
* Default: `0` (no timeout)
* `val_steps` Number
- * The number of brightness adjustment steps.
+ * The value by which to increment the brightness.
* Default: `8`
## Matrix {#matrix}
@@ -549,7 +549,7 @@ Configures the [RGB Lighting](features/rgblight) feature.
}
```
* `brightness_steps` Number
- * The number of brightness adjustment steps.
+ * The value by which to increment the brightness.
* Default: `17`
* `default`
* `animation` String
@@ -574,7 +574,7 @@ Configures the [RGB Lighting](features/rgblight) feature.
* The driver to use. Must be one of `apa102`, `custom`, `ws2812`.
* Default: `"ws2812"`
* `hue_steps` Number
- * The number of hue adjustment steps.
+ * The value by which to increment the hue.
* Default: `8`
* `layers`
* `blink` Boolean
@@ -593,7 +593,7 @@ Configures the [RGB Lighting](features/rgblight) feature.
* The maximum value which the HSV "V" component is scaled to, from 0 to 255.
* Default: `255`
* `saturation_steps` Number
- * The number of saturation adjustment steps.
+ * The value by which to increment the suturation.
* Default: `17`
* `sleep` Boolean
* Turn off the LEDs when the host goes to sleep.
@@ -645,7 +645,7 @@ Configures the [RGB Matrix](features/rgb_matrix) feature.
* `driver` String Required
* The driver to use. Must be one of `aw20216s`, `custom`, `is31fl3218`, `is31fl3236`, `is31fl3729`, `is31fl3731`, `is31fl3733`, `is31fl3736`, `is31fl3737`, `is31fl3741`, `is31fl3742a`, `is31fl3743a`, `is31fl3745`, `is31fl3746a`, `snled27351`, `ws2812`.
* `hue_steps` Number
- * The number of hue adjustment steps.
+ * The value by which to increment the hue.
* Default: `8`
* `layout` Array: Object Required
* List of LED configuration dictionaries. Each dictionary contains:
@@ -664,7 +664,7 @@ Configures the [RGB Matrix](features/rgb_matrix) feature.
* Default: `16`
* `led_process_limit` Number
* Limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness).
- * Default: `led_count / 5`
+ * Default: `(led_count + 4) / 5`
* `max_brightness` Number
* The maximum value which the HSV "V" component is scaled to, from 0 to 255.
* Default: `255`
@@ -672,13 +672,13 @@ Configures the [RGB Matrix](features/rgb_matrix) feature.
* Animations react to keyup instead of keydown.
* Default: `false`
* `sat_steps` Number
- * The number of saturation adjustment steps.
+ * The value by which to increment the saturation.
* Default: `16`
* `sleep` Boolean
* Turn off the LEDs when the host goes to sleep.
* Default: `false`
* `speed_steps` Number
- * The number of speed adjustment steps.
+ * The value by which to increment the speed.
* Default: `16`
* `split_count` Array: Number
* For split keyboards, the number of LEDs on each half.
@@ -687,7 +687,7 @@ Configures the [RGB Matrix](features/rgb_matrix) feature.
* The LED activity timeout in milliseconds.
* Default: `0` (no timeout)
* `val_steps` Number
- * The number of brightness adjustment steps.
+ * The value by which to increment the brightness.
* Default: `16`
## Secure {#secure}
diff --git a/keyboards/cannonkeys/link/config.h b/keyboards/cannonkeys/link/config.h
new file mode 100644
index 00000000000..c244f7a56b5
--- /dev/null
+++ b/keyboards/cannonkeys/link/config.h
@@ -0,0 +1,27 @@
+/* Copyright 2024 CannonKeys */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+/* VBUS-routed pin for upstream detection */
+#define USB_VBUS_PIN GP27
+
+#define SPLIT_HAND_PIN_LOW_IS_LEFT
+
+// Configure full duplex split comms over PIO
+#define SERIAL_USART_FULL_DUPLEX
+#define SERIAL_USART_TX_PIN GP28
+#define SERIAL_USART_RX_PIN GP29
+#define SERIAL_USART_PIN_SWAP
+
+/* RP2040- and hardware-specific config */
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U
+#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64
+
+/* I2C for OLEDs */
+#define I2C_DRIVER I2CD1
+#define I2C1_SDA_PIN GP14
+#define I2C1_SCL_PIN GP15
+
+#define OLED_DISPLAY_64X128
diff --git a/keyboards/cannonkeys/link/halconf.h b/keyboards/cannonkeys/link/halconf.h
new file mode 100644
index 00000000000..538c60c0b21
--- /dev/null
+++ b/keyboards/cannonkeys/link/halconf.h
@@ -0,0 +1,7 @@
+// Copyright 2024 Andrew Kannan
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#define HAL_USE_I2C TRUE
+#include_next
diff --git a/keyboards/cannonkeys/link/keyboard.json b/keyboards/cannonkeys/link/keyboard.json
new file mode 100644
index 00000000000..e5692cd4587
--- /dev/null
+++ b/keyboards/cannonkeys/link/keyboard.json
@@ -0,0 +1,135 @@
+{
+ "manufacturer": "CannonKeys",
+ "keyboard_name": "Link",
+ "maintainer": "awkannan",
+ "bootloader": "rp2040",
+ "bootmagic": {
+ "matrix": [0, 5]
+ },
+ "build": {
+ "debounce_type": "asym_eager_defer_pk"
+ },
+ "diode_direction": "COL2ROW",
+ "dynamic_keymap": {
+ "layer_count": 6
+ },
+ "encoder": {
+ "rotary": [
+ {"pin_a": "GP12", "pin_b": "GP13", "resolution": 2}
+ ]
+ },
+ "features": {
+ "bootmagic": true,
+ "encoder": true,
+ "extrakey": true,
+ "mousekey": true,
+ "nkro": true,
+ "oled": true
+ },
+ "matrix_pins": {
+ "cols": ["GP17", "GP18", "GP19", "GP20", "GP21", "GP24"],
+ "rows": ["GP25", "GP26", "GP16", "GP11", "GP10"]
+ },
+ "processor": "RP2040",
+ "qmk": {
+ "tap_keycode_delay": 10
+ },
+ "split": {
+ "bootmagic": {
+ "matrix": [5, 5]
+ },
+ "enabled": true,
+ "handedness": {
+ "pin": "GP8"
+ },
+ "matrix_pins": {
+ "right": {
+ "cols": ["GP16", "GP11", "GP10", "GP3", "GP2", "GP1"],
+ "rows": ["GP9", "GP0", "GP17", "GP18", "GP19"]
+ }
+ },
+ "serial": {
+ "driver": "vendor"
+ },
+ "transport": {
+ "sync": {
+ "layer_state": true,
+ "matrix_state": true,
+ "oled": true,
+ "wpm": true
+ }
+ }
+ },
+ "url": "https://cannonkeys.com/",
+ "usb": {
+ "device_version": "0.0.1",
+ "pid": "0x0038",
+ "vid": "0xCA04"
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"matrix": [0, 5], "x": 0, "y": 0},
+ {"matrix": [0, 4], "x": 1, "y": 0},
+ {"matrix": [0, 3], "x": 2, "y": 0},
+ {"matrix": [0, 2], "x": 3, "y": 0},
+ {"matrix": [0, 1], "x": 4, "y": 0},
+ {"matrix": [0, 0], "x": 5, "y": 0},
+ {"matrix": [5, 0], "x": 11, "y": 0},
+ {"matrix": [5, 1], "x": 12, "y": 0},
+ {"matrix": [5, 2], "x": 13, "y": 0},
+ {"matrix": [5, 3], "x": 14, "y": 0},
+ {"matrix": [5, 4], "x": 15, "y": 0},
+ {"matrix": [5, 5], "x": 16, "y": 0},
+ {"matrix": [1, 5], "x": 0, "y": 1},
+ {"matrix": [1, 4], "x": 1, "y": 1},
+ {"matrix": [1, 3], "x": 2, "y": 1},
+ {"matrix": [1, 2], "x": 3, "y": 1},
+ {"matrix": [1, 1], "x": 4, "y": 1},
+ {"matrix": [1, 0], "x": 5, "y": 1},
+ {"matrix": [6, 0], "x": 11, "y": 1},
+ {"matrix": [6, 1], "x": 12, "y": 1},
+ {"matrix": [6, 2], "x": 13, "y": 1},
+ {"matrix": [6, 3], "x": 14, "y": 1},
+ {"matrix": [6, 4], "x": 15, "y": 1},
+ {"matrix": [6, 5], "x": 16, "y": 1},
+ {"matrix": [2, 5], "x": 0, "y": 2},
+ {"matrix": [2, 4], "x": 1, "y": 2},
+ {"matrix": [2, 3], "x": 2, "y": 2},
+ {"matrix": [2, 2], "x": 3, "y": 2},
+ {"matrix": [2, 1], "x": 4, "y": 2},
+ {"matrix": [2, 0], "x": 5, "y": 2},
+ {"matrix": [7, 0], "x": 11, "y": 2},
+ {"matrix": [7, 1], "x": 12, "y": 2},
+ {"matrix": [7, 2], "x": 13, "y": 2},
+ {"matrix": [7, 3], "x": 14, "y": 2},
+ {"matrix": [7, 4], "x": 15, "y": 2},
+ {"matrix": [7, 5], "x": 16, "y": 2},
+ {"matrix": [3, 5], "x": 0, "y": 3},
+ {"matrix": [3, 4], "x": 1, "y": 3},
+ {"matrix": [3, 3], "x": 2, "y": 3},
+ {"matrix": [3, 2], "x": 3, "y": 3},
+ {"matrix": [3, 1], "x": 4, "y": 3},
+ {"matrix": [3, 0], "x": 5, "y": 3},
+ {"matrix": [4, 5], "x": 6, "y": 3},
+ {"matrix": [9, 5], "x": 10, "y": 3},
+ {"matrix": [8, 0], "x": 11, "y": 3},
+ {"matrix": [8, 1], "x": 12, "y": 3},
+ {"matrix": [8, 2], "x": 13, "y": 3},
+ {"matrix": [8, 3], "x": 14, "y": 3},
+ {"matrix": [8, 4], "x": 15, "y": 3},
+ {"matrix": [8, 5], "x": 16, "y": 3},
+ {"matrix": [4, 4], "x": 2, "y": 4},
+ {"matrix": [4, 3], "x": 3, "y": 4},
+ {"matrix": [4, 2], "x": 4, "y": 4},
+ {"matrix": [4, 1], "x": 5, "y": 4},
+ {"matrix": [4, 0], "x": 6, "y": 4, "h": 1.5},
+ {"matrix": [9, 0], "x": 10, "y": 4, "h": 1.5},
+ {"matrix": [9, 1], "x": 11, "y": 4},
+ {"matrix": [9, 2], "x": 12, "y": 4},
+ {"matrix": [9, 3], "x": 13, "y": 4},
+ {"matrix": [9, 4], "x": 14, "y": 4}
+ ]
+ }
+ }
+}
diff --git a/keyboards/cannonkeys/link/keymaps/default/keymap.c b/keyboards/cannonkeys/link/keymaps/default/keymap.c
new file mode 100644
index 00000000000..eba810d8682
--- /dev/null
+++ b/keyboards/cannonkeys/link/keymaps/default/keymap.c
@@ -0,0 +1,31 @@
+// Copyright 2025 Andrew Kannan (awkannan)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+[0] = LAYOUT(
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
+ KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
+ KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_MUTE, KC_MPLY, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
+ KC_LGUI, KC_LALT, KC_LCTL, MO(1), KC_ENT, KC_SPC, MO(2), KC_RCTL, KC_RALT, KC_RGUI
+),
+
+[1] = LAYOUT(
+ KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_F12,
+ KC_WREF, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_PIPE,
+ KC_TRNS, KC_EQL, KC_MINS, KC_PLUS, KC_LCBR, KC_RCBR, KC_TRNS, KC_TRNS, KC_LBRC, KC_RBRC, KC_DOT, KC_COLN, KC_BSLS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+),
+
+[2] = LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ QK_BOOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_HOME, KC_UP, KC_END, KC_INS, KC_DEL,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_CAPS, KC_PGUP, KC_MPRV, KC_MNXT, KC_PSCR, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
+)
+};
diff --git a/keyboards/cannonkeys/link/link.c b/keyboards/cannonkeys/link/link.c
new file mode 100644
index 00000000000..2d0d2cb5572
--- /dev/null
+++ b/keyboards/cannonkeys/link/link.c
@@ -0,0 +1,93 @@
+// Copyright 2025 Andrew Kannan (awkannan)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "quantum.h"
+
+#ifdef OLED_ENABLE
+oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
+ if (is_keyboard_master()) {
+ return OLED_ROTATION_0;
+ } else {
+ return OLED_ROTATION_90;
+ }
+ return rotation;
+}
+
+static void render_logo(void) {
+ static const char PROGMEM qmk_logo[] = {
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,
+ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,
+ 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0
+ };
+ oled_write_P(qmk_logo, false);
+}
+
+void print_status_narrow(void) {
+ oled_write_P(PSTR("\n\n"), false);
+ switch (get_highest_layer(layer_state)) {
+ case 0:
+ oled_write_ln_P(PSTR("Qwrt"), false);
+ break;
+ case 1:
+ oled_write_ln_P(PSTR("Clmk"), false);
+ break;
+ default:
+ oled_write_P(PSTR("Mod\n"), false);
+ break;
+ }
+ oled_write_P(PSTR("\n\n"), false);
+ oled_write_ln_P(PSTR("LAYER"), false);
+ switch (get_highest_layer(layer_state)) {
+ case 0:
+ case 1:
+ oled_write_P(PSTR("Base\n"), false);
+ break;
+ case 2:
+ oled_write_P(PSTR("Raise"), false);
+ break;
+ case 3:
+ oled_write_P(PSTR("Lower"), false);
+ break;
+ default:
+ oled_write_ln_P(PSTR("Undef"), false);
+ }
+ oled_write_P(PSTR("\n\n"), false);
+ led_t led_usb_state = host_keyboard_led_state();
+ oled_write_ln_P(PSTR("CPSLK"), led_usb_state.caps_lock);
+}
+
+bool oled_task_kb(void) {
+ if (!oled_task_user()) {
+ return false;
+ }
+ if (is_keyboard_master()) {
+ print_status_narrow();
+ } else {
+ render_logo();
+ }
+ return true;
+}
+
+#endif
+
+#ifdef ENCODER_ENABLE
+bool encoder_update_kb(uint8_t index, bool clockwise) {
+ if (!encoder_update_user(index, clockwise)) {
+ return false;
+ }
+ if (index == 0) {
+ if (clockwise) {
+ tap_code(KC_VOLU);
+ } else {
+ tap_code(KC_VOLD);
+ }
+ } else if (index == 1) {
+ if (clockwise) {
+ tap_code(KC_PGDN);
+ } else {
+ tap_code(KC_PGUP);
+ }
+ }
+ return true;
+}
+#endif
diff --git a/keyboards/cannonkeys/link/readme.md b/keyboards/cannonkeys/link/readme.md
new file mode 100644
index 00000000000..461be861800
--- /dev/null
+++ b/keyboards/cannonkeys/link/readme.md
@@ -0,0 +1,27 @@
+# Link
+
+The Link is a Sofle58 inspired Ergo Split keyboard from CannonKeys.
+It uses 1.3" SH1107 screens and ALPS EC11 compatible encoders.
+
+* Keyboard Maintainer: [Andrew Kannan](https://github.com/awkannan)
+* Hardware Supported: RP2040
+* Hardware Availability: [CannonKeys](https://cannonkeys.com)
+
+
+Make example for this keyboard (after setting up your build environment):
+
+ make cannonkeys/link:default
+
+Flashing example for this keyboard:
+
+ make cannonkeys/link:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the top-most and outer-most key in the matrix and plug in the keyboard
+* **Physical reset button**: Hold the "BOOTMODE" button on the back of the PCB and briefly press the "RESET" button on the back of the PCB
+* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
diff --git a/keyboards/cannonkeys/vida/config.h b/keyboards/cannonkeys/vida/config.h
new file mode 100644
index 00000000000..4eec357f201
--- /dev/null
+++ b/keyboards/cannonkeys/vida/config.h
@@ -0,0 +1,9 @@
+// Copyright 2024 Andrew Kannan
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U
+
+#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64
diff --git a/keyboards/cannonkeys/vida/hotswap/keyboard.json b/keyboards/cannonkeys/vida/hotswap/keyboard.json
new file mode 100644
index 00000000000..a2278354e57
--- /dev/null
+++ b/keyboards/cannonkeys/vida/hotswap/keyboard.json
@@ -0,0 +1,272 @@
+{
+ "keyboard_name": "Vida HS",
+ "usb": {
+ "pid": "0x0035"
+ },
+ "community_layouts": ["60_ansi", "60_ansi_split_bs_rshift", "60_ansi_tsangan", "60_hhkb"],
+ "layout_aliases": {
+ "LAYOUT_60_ansi_split_bs_rshift": "LAYOUT_all"
+ },
+ "layouts": {
+ "LAYOUT_60_ansi": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0, "w": 2},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 2.75},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25}
+ ]
+ },
+ "LAYOUT_60_ansi_tsangan": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0, "w": 2},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 2.75},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
+ {"matrix": [4, 1], "x": 1.5, "y": 4},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
+ {"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
+ {"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
+ {"matrix": [4, 12], "x": 12.5, "y": 4},
+ {"matrix": [4, 13], "x": 13.5, "y": 4, "w": 1.5}
+ ]
+ },
+ "LAYOUT_60_hhkb": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [2, 12], "x": 14, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 13], "x": 14, "y": 3},
+ {"matrix": [4, 1], "x": 1.5, "y": 4},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
+ {"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
+ {"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
+ {"matrix": [4, 12], "x": 12.5, "y": 4}
+ ]
+ },
+ "LAYOUT_all": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [2, 12], "x": 14, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 13], "x": 14, "y": 3},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25}
+ ]
+ }
+ }
+}
diff --git a/keyboards/cannonkeys/vida/hotswap/keymaps/default/keymap.c b/keyboards/cannonkeys/vida/hotswap/keymaps/default/keymap.c
new file mode 100644
index 00000000000..8ff252918f3
--- /dev/null
+++ b/keyboards/cannonkeys/vida/hotswap/keymaps/default/keymap.c
@@ -0,0 +1,27 @@
+// Copyright 2023 Andrew Kannan
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+enum layer_names {
+ _BASE,
+ _FN1
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE] = LAYOUT_all(
+ QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_FN1),
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(_FN1), KC_RCTL
+ ),
+
+ [_FN1] = LAYOUT_all(
+ QK_GESC, 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_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ KC_GRV, _______, _______, _______, _______, _______, _______, QK_BOOT
+ )
+};
diff --git a/keyboards/cannonkeys/vida/info.json b/keyboards/cannonkeys/vida/info.json
new file mode 100644
index 00000000000..8a5ddfe8bd1
--- /dev/null
+++ b/keyboards/cannonkeys/vida/info.json
@@ -0,0 +1,28 @@
+{
+ "manufacturer": "CannonKeys",
+ "maintainer": "awkannan",
+ "bootloader": "rp2040",
+ "diode_direction": "COL2ROW",
+ "features": {
+ "bootmagic": true,
+ "command": false,
+ "console": false,
+ "extrakey": true,
+ "mousekey": true,
+ "nkro": true
+ },
+ "indicators": {
+ "caps_lock": "GP29",
+ "on_state": 0
+ },
+ "matrix_pins": {
+ "cols": ["GP28", "GP8", "GP14", "GP13", "GP12", "GP11", "GP10", "GP9", "GP6", "GP5", "GP4", "GP3", "GP2", "GP1"],
+ "rows": ["GP26", "GP27", "GP15", "GP16", "GP17"]
+ },
+ "processor": "RP2040",
+ "url": "https://cannonkeys.com",
+ "usb": {
+ "device_version": "0.0.1",
+ "vid": "0xCA04"
+ }
+}
diff --git a/keyboards/cannonkeys/vida/readme.md b/keyboards/cannonkeys/vida/readme.md
new file mode 100644
index 00000000000..2143a7d20ad
--- /dev/null
+++ b/keyboards/cannonkeys/vida/readme.md
@@ -0,0 +1,31 @@
+# Vida Keyboard PCB
+
+Vida PCB from CannonKeys
+
+This folder has files for both the wired hotswap and solderable versions of the Vida PCB
+
+The hotswap version does not have as much layout support as the solderable version (no ISO, no split space)
+The hotswap version does not support per key LED backlighting
+
+* Keyboard Maintainer: [Andrew Kannan](https://github.com/awkannan)
+* Hardware Supported: RP2040
+* Hardware Availability: [CannonKeys](https://cannonkeys.com)
+
+
+Make example for this keyboard (after setting up your build environment):
+
+ make cannonkeys/vida:hotswap:default
+
+Flashing example for this keyboard:
+
+ make cannonkeys/vida:hotswap:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
+* **Physical reset button**: Hold the "BOOTMODE" button on the back of the PCB and briefly press the "RESET" button on the back of the PCB
+* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
diff --git a/keyboards/cannonkeys/vida/solderable/config.h b/keyboards/cannonkeys/vida/solderable/config.h
new file mode 100644
index 00000000000..9a8669d7a85
--- /dev/null
+++ b/keyboards/cannonkeys/vida/solderable/config.h
@@ -0,0 +1,7 @@
+// Copyright 2024 Andrew Kannan
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#define BACKLIGHT_PWM_DRIVER PWMD3
+#define BACKLIGHT_PWM_CHANNEL RP2040_PWM_CHANNEL_A
diff --git a/keyboards/cannonkeys/vida/solderable/halconf.h b/keyboards/cannonkeys/vida/solderable/halconf.h
new file mode 100644
index 00000000000..0536c37ff34
--- /dev/null
+++ b/keyboards/cannonkeys/vida/solderable/halconf.h
@@ -0,0 +1,8 @@
+// Copyright 2024 Andrew Kannan
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#define HAL_USE_PWM TRUE
+
+#include_next
diff --git a/keyboards/cannonkeys/vida/solderable/keyboard.json b/keyboards/cannonkeys/vida/solderable/keyboard.json
new file mode 100644
index 00000000000..1b8635b4438
--- /dev/null
+++ b/keyboards/cannonkeys/vida/solderable/keyboard.json
@@ -0,0 +1,680 @@
+{
+ "keyboard_name": "Vida",
+ "backlight": {
+ "breathing": true,
+ "breathing_period": 5,
+ "levels": 15,
+ "pin": "GP22"
+ },
+ "features": {
+ "backlight": true
+ },
+ "usb": {
+ "pid": "0x0032"
+ },
+ "community_layouts": ["60_ansi", "60_ansi_split_bs_rshift", "60_ansi_tsangan", "60_hhkb", "60_iso", "60_iso_split_bs_rshift", "60_iso_tsangan"],
+ "layouts": {
+ "LAYOUT_60_ansi": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0, "w": 2},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 2.75},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25}
+ ]
+ },
+ "LAYOUT_60_ansi_split_bs_rshift": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [2, 12], "x": 14, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 13], "x": 14, "y": 3},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25}
+ ]
+ },
+ "LAYOUT_60_ansi_tsangan": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0, "w": 2},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 2.75},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
+ {"matrix": [4, 1], "x": 1.5, "y": 4},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
+ {"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
+ {"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
+ {"matrix": [4, 12], "x": 12.5, "y": 4},
+ {"matrix": [4, 13], "x": 13.5, "y": 4, "w": 1.5}
+ ]
+ },
+ "LAYOUT_60_hhkb": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [2, 12], "x": 14, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 13], "x": 14, "y": 3},
+ {"matrix": [4, 1], "x": 1.5, "y": 4},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
+ {"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
+ {"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
+ {"matrix": [4, 12], "x": 12.5, "y": 4}
+ ]
+ },
+ "LAYOUT_60_iso": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0, "w": 2},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [1, 13], "x": 12.75, "y": 2},
+ {"matrix": [2, 13], "x": 13.75, "y": 1, "w": 1.25, "h": 2},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 1.25},
+ {"matrix": [3, 1], "x": 1.25, "y": 3},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 2.75},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25}
+ ]
+ },
+ "LAYOUT_60_iso_split_bs_rshift": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [2, 12], "x": 14, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [1, 13], "x": 12.75, "y": 2},
+ {"matrix": [2, 13], "x": 13.75, "y": 1, "w": 1.25, "h": 2},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 1.25},
+ {"matrix": [3, 1], "x": 1.25, "y": 3},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 13], "x": 14, "y": 3},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25}
+ ]
+ },
+ "LAYOUT_60_iso_tsangan": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0, "w": 2},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [1, 13], "x": 12.75, "y": 2},
+ {"matrix": [2, 13], "x": 13.75, "y": 1, "w": 1.25, "h": 2},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 1.25},
+ {"matrix": [3, 1], "x": 1.25, "y": 3},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 2.75},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
+ {"matrix": [4, 1], "x": 1.5, "y": 4},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
+ {"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
+ {"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
+ {"matrix": [4, 12], "x": 12.5, "y": 4},
+ {"matrix": [4, 13], "x": 13.5, "y": 4, "w": 1.5}
+ ]
+ },
+ "LAYOUT_60_iso_tsangan_split_bs_rshift": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [2, 12], "x": 14, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [1, 13], "x": 12.75, "y": 2},
+ {"matrix": [2, 13], "x": 13.75, "y": 1, "w": 1.25, "h": 2},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 1.25},
+ {"matrix": [3, 1], "x": 1.25, "y": 3},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 13], "x": 14, "y": 3},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
+ {"matrix": [4, 1], "x": 1.5, "y": 4},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
+ {"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
+ {"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
+ {"matrix": [4, 12], "x": 12.5, "y": 4},
+ {"matrix": [4, 13], "x": 13.5, "y": 4, "w": 1.5}
+ ]
+ },
+ "LAYOUT_60_tsangan_hhkb": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [2, 12], "x": 14, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 13], "x": 14, "y": 3},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
+ {"matrix": [4, 1], "x": 1.5, "y": 4},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
+ {"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
+ {"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
+ {"matrix": [4, 12], "x": 12.5, "y": 4},
+ {"matrix": [4, 13], "x": 13.5, "y": 4, "w": 1.5}
+ ]
+ },
+ "LAYOUT_all": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [2, 12], "x": 14, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 1.25},
+ {"matrix": [3, 1], "x": 1.25, "y": 3},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 13], "x": 14, "y": 3},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 5], "x": 3.75, "y": 4, "w": 2.25},
+ {"matrix": [4, 6], "x": 6, "y": 4, "w": 1.25},
+ {"matrix": [4, 9], "x": 7.25, "y": 4, "w": 2.75},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25}
+ ]
+ }
+ }
+}
diff --git a/keyboards/cannonkeys/vida/solderable/keymaps/default/keymap.c b/keyboards/cannonkeys/vida/solderable/keymaps/default/keymap.c
new file mode 100644
index 00000000000..46d376f42d0
--- /dev/null
+++ b/keyboards/cannonkeys/vida/solderable/keymaps/default/keymap.c
@@ -0,0 +1,27 @@
+// Copyright 2023 Andrew Kannan
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+enum layer_names {
+ _BASE,
+ _FN1
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE] = LAYOUT_all(
+ QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_FN1),
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, KC_RGUI, MO(_FN1), KC_RCTL
+ ),
+
+ [_FN1] = LAYOUT_all(
+ QK_GESC, 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_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ BL_BRTG, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ BL_UP, _______, BL_DOWN, BL_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ KC_GRV, _______, _______, _______, _______, _______, _______, _______, _______, QK_BOOT
+ )
+};
diff --git a/keyboards/cannonkeys/vida/solderable/matrix_diagram.md b/keyboards/cannonkeys/vida/solderable/matrix_diagram.md
new file mode 100644
index 00000000000..6de584cb4eb
--- /dev/null
+++ b/keyboards/cannonkeys/vida/solderable/matrix_diagram.md
@@ -0,0 +1,24 @@
+# Matrix Diagram for CannonKeys Vida
+
+```
+ ┌───────┐
+ 2u Backspace │0D │
+ └───────┘
+┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
+│00 │01 │02 │03 │04 │05 │06 │07 │08 │09 │0A │0B │0C │0D │2C │
+├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┤ ┌─────┐
+│10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1A │1B │1C │1D │ │ │
+├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ ┌──┴┐2D │ ISO Enter
+│20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2A │2B │2D │ │1D │ │
+├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┤ └───┴────┘
+│30 │31 │32 │33 │34 │35 │36 │37 │38 │39 │3A │3B │3C │3D │
+├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬┴───┤
+│40 │41 │42 │46 │4A │4B │4C │4D │
+└────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
+┌────────┐ ┌──────────┐
+│30 │ 2.25u LShift 2.75u RShift │3C │
+└────────┘ └──────────┘
+┌─────┬───┬─────┬───────────────────────────┬─────┬───┬─────┐
+│40 │41 │42 │46 │4B │4C │4D │ Tsangan/WKL/HHKB
+└─────┴───┴─────┴───────────────────────────┴─────┴───┴─────┘
+```
diff --git a/keyboards/cannonkeys/vida/solderable/mcuconf.h b/keyboards/cannonkeys/vida/solderable/mcuconf.h
new file mode 100644
index 00000000000..200f75c11b4
--- /dev/null
+++ b/keyboards/cannonkeys/vida/solderable/mcuconf.h
@@ -0,0 +1,9 @@
+// Copyright 2024 Andrew Kannan
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include_next
+
+#undef RP_PWM_USE_PWM3
+#define RP_PWM_USE_PWM3 TRUE
diff --git a/keyboards/coban/pad12a/config.h b/keyboards/coban/pad12a/config.h
new file mode 100644
index 00000000000..b6b096ad05d
--- /dev/null
+++ b/keyboards/coban/pad12a/config.h
@@ -0,0 +1,7 @@
+// Copyright 2025 RyanDam (https://github.com/RyanDam)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U
diff --git a/keyboards/coban/pad12a/keyboard.json b/keyboards/coban/pad12a/keyboard.json
new file mode 100644
index 00000000000..dc027d46f41
--- /dev/null
+++ b/keyboards/coban/pad12a/keyboard.json
@@ -0,0 +1,50 @@
+{
+ "keyboard_name": "Coban Pad 12A",
+ "name": "Coban Pad 12A",
+ "url": "https://cobanstationery.com",
+ "maintainer": "Coban Stationery",
+ "manufacturer": "Coban Stationery",
+ "usb": {
+ "pid": "0xC12A",
+ "vid": "0xCB3A",
+ "device_version": "1.0.0"
+ },
+ "matrix_pins": {
+ "cols": ["GP18", "GP16", "GP11", "GP10"],
+ "rows": ["GP19", "GP17", "GP12"]
+ },
+ "diode_direction": "ROW2COL",
+ "encoder": {
+ "rotary": [
+ {"pin_a": "GP20", "pin_b": "GP21"}
+ ]
+ },
+ "processor": "RP2040",
+ "bootloader": "rp2040",
+ "features": {
+ "bootmagic": true,
+ "encoder": true,
+ "extrakey": true,
+ "mousekey": true
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+
+ {"matrix": [1, 0], "x": 0, "y": 1},
+ {"matrix": [1, 1], "x": 1, "y": 1},
+ {"matrix": [1, 2], "x": 2, "y": 1},
+ {"matrix": [1, 3], "x": 3, "y": 1},
+
+ {"matrix": [2, 0], "x": 0, "y": 2},
+ {"matrix": [2, 1], "x": 1, "y": 2},
+ {"matrix": [2, 2], "x": 2, "y": 2},
+ {"matrix": [2, 3], "x": 3, "y": 2}
+ ]
+ }
+ }
+}
diff --git a/keyboards/coban/pad12a/keymaps/default/keymap.c b/keyboards/coban/pad12a/keymaps/default/keymap.c
new file mode 100644
index 00000000000..0ef7814f630
--- /dev/null
+++ b/keyboards/coban/pad12a/keymaps/default/keymap.c
@@ -0,0 +1,19 @@
+// Copyright 2025 RyanDam (https://github.com/RyanDam)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT(
+ KC_MPLY, KC_MPRV, KC_MUTE, KC_MNXT,
+ KC_PGUP, KC_ESC, KC_UP, KC_ENT,
+ KC_PGDN, KC_LEFT, KC_DOWN, KC_RIGHT
+ ),
+};
+
+
+#if defined(ENCODER_MAP_ENABLE)
+const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
+ [0] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) },
+};
+#endif
diff --git a/keyboards/coban/pad12a/keymaps/default/rules.mk b/keyboards/coban/pad12a/keymaps/default/rules.mk
new file mode 100644
index 00000000000..ee325681483
--- /dev/null
+++ b/keyboards/coban/pad12a/keymaps/default/rules.mk
@@ -0,0 +1 @@
+ENCODER_MAP_ENABLE = yes
diff --git a/keyboards/coban/pad12a/readme.md b/keyboards/coban/pad12a/readme.md
new file mode 100644
index 00000000000..92b5b4528b9
--- /dev/null
+++ b/keyboards/coban/pad12a/readme.md
@@ -0,0 +1,23 @@
+# Coban Pad 12A
+
+
+Small ortho keyboard with 11 hotswapable buttons and 1 encoder
+
+* Keyboard Maintainer: [RyanDam](https://github.com/RyanDam)
+* Hardware Supported: Coban Pad 12A
+
+Make example for this keyboard (after setting up your build environment):
+
+ make coban/pad12a:default
+
+Flashing example for this keyboard:
+
+ make coban/pad12a:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader:
+
+* **boot button**: Hold the BOOT button on the back of the PCB while plug in usb cable
diff --git a/keyboards/coban/pad9a/keyboard.json b/keyboards/coban/pad9a/keyboard.json
index 1b5efb34567..d34f2b000b6 100644
--- a/keyboards/coban/pad9a/keyboard.json
+++ b/keyboards/coban/pad9a/keyboard.json
@@ -69,7 +69,7 @@
{"label": "key_3", "matrix": [0, 4], "x": 2, "y": 1},
{"label": "key_4", "matrix": [0, 5], "x": 0, "y": 2},
{"label": "key_5", "matrix": [0, 6], "x": 1, "y": 2},
- {"label": "key_6", "matrix": [0, 7], "x": 2, "y": 3}
+ {"label": "key_6", "matrix": [0, 7], "x": 2, "y": 2}
]
}
}
diff --git a/keyboards/djreisch/lumpy27/keyboard.json b/keyboards/djreisch/lumpy27/keyboard.json
new file mode 100644
index 00000000000..d6c4b180bd8
--- /dev/null
+++ b/keyboards/djreisch/lumpy27/keyboard.json
@@ -0,0 +1,55 @@
+{
+ "manufacturer": "djreisch",
+ "keyboard_name": "LumPy27",
+ "maintainer": "djreisch",
+ "board": "GENERIC_RP_RP2040",
+ "bootloader": "rp2040",
+ "diode_direction": "COL2ROW",
+ "features": {
+ "bootmagic": true,
+ "extrakey": true,
+ "mousekey": true
+ },
+ "matrix_pins": {
+ "cols": ["GP0", "GP1", "GP2", "GP3", "GP4", "GP5"],
+ "rows": ["GP14", "GP15", "GP16", "GP17", "GP18"]
+ },
+ "processor": "RP2040",
+ "usb": {
+ "device_version": "1.0.0",
+ "pid": "0x2326",
+ "vid": "0xFEED"
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1},
+ {"matrix": [1, 1], "x": 1, "y": 1},
+ {"matrix": [1, 2], "x": 2, "y": 1},
+ {"matrix": [1, 3], "x": 3, "y": 1},
+ {"matrix": [1, 4], "x": 4, "y": 1},
+ {"matrix": [1, 5], "x": 5, "y": 1},
+ {"matrix": [2, 1], "x": 1, "y": 2},
+ {"matrix": [2, 2], "x": 2, "y": 2},
+ {"matrix": [2, 3], "x": 3, "y": 2},
+ {"matrix": [2, 4], "x": 4, "y": 2},
+ {"matrix": [2, 5], "x": 5, "y": 2},
+ {"matrix": [3, 0], "x": 0, "y": 3},
+ {"matrix": [3, 1], "x": 1, "y": 3},
+ {"matrix": [3, 2], "x": 2, "y": 3},
+ {"matrix": [3, 3], "x": 3, "y": 3},
+ {"matrix": [3, 4], "x": 4, "y": 3},
+ {"matrix": [3, 5], "x": 5, "y": 3},
+ {"matrix": [4, 3], "x": 3, "y": 4},
+ {"matrix": [4, 4], "x": 4, "y": 4},
+ {"matrix": [4, 5], "x": 5, "y": 4}
+ ]
+ }
+ }
+}
diff --git a/keyboards/djreisch/lumpy27/keymaps/default/keymap.c b/keyboards/djreisch/lumpy27/keymaps/default/keymap.c
new file mode 100644
index 00000000000..48897c80648
--- /dev/null
+++ b/keyboards/djreisch/lumpy27/keymaps/default/keymap.c
@@ -0,0 +1,76 @@
+/* Copyright 2024 Daniel Reisch (djreisch)
+ *
+ * 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 QMK_KEYBOARD_H
+
+enum custom_keycodes { MACRO_GG = QK_USER };
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /*
+ Main
+ ,-----------------------------------------.
+ | ESC | 1 | 2 | 3 | 4 | 5 |
+ |------+------+------+------+------+------|
+ | Tab | G | Q | W | E | R |
+ |------+------+------+------+------+------|
+ | LSHIFT | A | S | D | F |
+ |------+------+------+------+------+------|
+ | LCTL | B | Z | X | C | V |-------|
+ `-----------------------------------------/ /
+ | LAlt | FN | / Space /
+ | | |/ /
+ `---------------------'
+ */
+ [0] = LAYOUT(KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5,
+ KC_TAB, KC_G, KC_Q, KC_W, KC_E, KC_R,
+ KC_LSFT, KC_A, KC_S, KC_D, KC_F,
+ KC_LCTL, KC_B, KC_Z, KC_X, KC_C, KC_V,
+ KC_LALT, MO(1), KC_SPACE),
+
+ /*
+ Alt
+ ,-----------------------------------------.
+ | ESC | 0 | 9 | 8 | 7 | 6 |
+ |------+------+------+------+------+------|
+ | F1 | F2 | F3 | F4 | F5 | F6 |
+ |------+------+------+------+------+------|
+ | LSHIFT | A | S | Y | H |
+ |------+------+------+------+------+------|
+ | LCTL | B | Z | X | C | M |-------|
+ `-----------------------------------------/ /
+ | LAlt | FN | / Enter /
+ | | |/ /
+ `---------------------'
+ */
+ [1] = LAYOUT(KC_ESC, KC_0, KC_9, KC_8, KC_7, KC_6,
+ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6,
+ KC_LSFT, KC_A, KC_S, KC_Y, KC_H,
+ KC_LCTL, MACRO_GG, KC_Z, KC_X, KC_C, KC_M,
+ KC_LALT, KC_TRNS, KC_ENTER)
+};
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case MACRO_GG:
+ if (record->event.pressed) {
+ // when keycode MACRO_GG is pressed, press shift+enter, send string "gg" and press enter
+ SEND_STRING(SS_DOWN(X_LSFT) SS_DELAY(10) SS_TAP(X_ENTER) SS_UP(X_LSFT) "gg" SS_TAP(X_ENTER));
+ }
+ break;
+ }
+
+ return true;
+}
diff --git a/keyboards/djreisch/lumpy27/readme.md b/keyboards/djreisch/lumpy27/readme.md
new file mode 100644
index 00000000000..da7d1ca92b2
--- /dev/null
+++ b/keyboards/djreisch/lumpy27/readme.md
@@ -0,0 +1,29 @@
+# LumPy27
+
+The Lightweight User-Modifiable Pi/Python keyboard is a 26-key ergonomic gaming keyboard running on an RP2040. Originally designed to run CircuitPython and KMK, since QMK supports the RP2040 bootloader this is now an additional option for firmware.
+
+Q: Why is it named the LumPy27 even though it has 26 keys?
+
+A: When originally designing the PCB and coming up with a name, I miscounted the switches. With the name emblazoned on the silkscreen I figured it sounded better than LumPy26.
+
+Q: Why are the keys in the wrong place?
+
+A: For certain games I found it easier instead of remapping them to just change where they are. That's why keys like B and G are not in the right spots.
+
+* Keyboard Maintainer: [djreisch](https://github.com/djreisch)
+* Hardware Availability: [DuckyDebug.org](https://duckydebug.org/products/lumpy27-ergonomic-gaming-keyboard)
+
+qmk compile example for this keyboard (after setting up your build environment):
+
+ qmk compile -kb djreisch/lumpy27 -km default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 2 ways:
+
+* **Bootloader Reset**: Hold down the bootload button and press the reset button
+* **Bootloader Power On**: Hold down the bootloader button and plug in the keyboard
+
+
diff --git a/keyboards/handwired/footy/config.h b/keyboards/handwired/footy/config.h
new file mode 100644
index 00000000000..5a081f79d69
--- /dev/null
+++ b/keyboards/handwired/footy/config.h
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
+#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U
diff --git a/keyboards/handwired/footy/keyboard.json b/keyboards/handwired/footy/keyboard.json
new file mode 100644
index 00000000000..eef8c250386
--- /dev/null
+++ b/keyboards/handwired/footy/keyboard.json
@@ -0,0 +1,35 @@
+{
+ "manufacturer": "CJ Pais",
+ "keyboard_name": "Footy",
+ "maintainer": "cjpais",
+ "bootloader": "rp2040",
+ "diode_direction": "COL2ROW",
+ "features": {
+ "bootmagic": true,
+ "extrakey": true,
+ "mousekey": true
+ },
+ "bootmagic": {
+ "matrix": [0, 1]
+ },
+ "matrix_pins": {
+ "cols": ["GP11", "GP10", "GP15"],
+ "rows": ["GP14"]
+ },
+ "processor": "RP2040",
+ "url": "https://workshop.cjpais.com/projects/footy",
+ "usb": {
+ "device_version": "1.0.0",
+ "pid": "0x0001",
+ "vid": "0x636A"
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0}
+ ]
+ }
+ }
+}
diff --git a/keyboards/handwired/footy/keymaps/default/keymap.json b/keyboards/handwired/footy/keymaps/default/keymap.json
new file mode 100644
index 00000000000..99804041d85
--- /dev/null
+++ b/keyboards/handwired/footy/keymaps/default/keymap.json
@@ -0,0 +1,10 @@
+{
+ "keyboard": "handwired/footy",
+ "keymap": "default",
+ "layout": "LAYOUT",
+ "layers": [
+ [
+ "KC_A", "KC_B", "KC_C"
+ ]
+ ]
+}
diff --git a/keyboards/handwired/footy/keymaps/handy/keymap.json b/keyboards/handwired/footy/keymaps/handy/keymap.json
new file mode 100644
index 00000000000..e2a2db6d10b
--- /dev/null
+++ b/keyboards/handwired/footy/keymaps/handy/keymap.json
@@ -0,0 +1,15 @@
+{
+ "keyboard": "handwired/footy",
+ "keymap": "handy",
+ "layout": "LAYOUT",
+ "layers": [
+ [
+ "KC_NO", "MT(MOD_RCTL | MOD_RGUI, KC_NO)", "KC_NO"
+ ]
+ ],
+ "config": {
+ "tapping": {
+ "term": 50
+ }
+ }
+}
diff --git a/keyboards/handwired/footy/keymaps/superwhisper/keymap.json b/keyboards/handwired/footy/keymaps/superwhisper/keymap.json
new file mode 100644
index 00000000000..0cfa41f502e
--- /dev/null
+++ b/keyboards/handwired/footy/keymaps/superwhisper/keymap.json
@@ -0,0 +1,15 @@
+{
+ "keyboard": "handwired/footy",
+ "keymap": "superwhisper",
+ "layout": "LAYOUT",
+ "layers": [
+ [
+ "KC_NO", "LOPT(KC_SPACE)", "KC_NO"
+ ]
+ ],
+ "config": {
+ "tapping": {
+ "term": 50
+ }
+ }
+}
diff --git a/keyboards/handwired/footy/readme.md b/keyboards/handwired/footy/readme.md
new file mode 100644
index 00000000000..6d02fad95cc
--- /dev/null
+++ b/keyboards/handwired/footy/readme.md
@@ -0,0 +1,42 @@
+# Footy
+
+
+
+*Footy is a foot pedal intended to be used with a speech to text application like 'handy' or superwhisper. Initially developed as an assistive technology device for those with limited typing abilities.*
+
+* Keyboard Maintainer: [CJ Pais](https://github.com/cjpais)
+* Hardware Supported: [Keebio Stampy](https://keeb.io/products/stampy-rp2040-usb-c-controller-board-for-handwiring)
+* Hardware Availability: [3D printed case](https://makerworld.com/en/models/1185240-footy)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make handwired/footy:default
+
+Flashing example for this keyboard (enter the bootloader first):
+
+ make handwired/footy:default:flash
+
+or drag and drop .uf2 file on the removable storage
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader:
+
+* **Physical reset button**: Briefly double press the button on the back of the PCB
+
+## Keymaps
+
+Right now there are two primary keymaps, one for 'handy' and one for 'superwhisper'.
+
+Handy's default keymap is for the center switch to be RCTRL + RGUI.
+
+Superwhisper's default keymap is for the center switch to be LOPT + SPACE.
+
+You can build either of these firmware images by running the following commands:
+
+```
+make handwired/footy:handy
+make handwired/footy:superwhisper
+```
\ No newline at end of file
diff --git a/keyboards/keyten/ortho_slayer/keyboard.json b/keyboards/keyten/ortho_slayer/keyboard.json
new file mode 100644
index 00000000000..e0232989371
--- /dev/null
+++ b/keyboards/keyten/ortho_slayer/keyboard.json
@@ -0,0 +1,117 @@
+{
+ "manufacturer": "keyten x La-Versa",
+ "keyboard_name": "Ortho Slayer",
+ "maintainer": "key10iq",
+ "processor": "STM32F072",
+ "bootloader": "stm32-dfu",
+ "usb": {
+ "vid": "0xEB69",
+ "pid": "0x9001",
+ "device_version": "0.0.1"
+ },
+ "features": {
+ "bootmagic": true,
+ "extrakey": true,
+ "mousekey": true,
+ "nkro": true
+ },
+ "diode_direction": "ROW2COL",
+ "matrix_pins": {
+ "rows": ["B6", "B4", "A15", "B0", "B1", "A6", "B15", "B11", "A9", "B13"],
+ "cols": ["B7", "B14", "B5", "A8", "B3", "A10", "A14", "B12", "A7", "B2", "B10"]
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ { "matrix": [0, 0], "x": 0, "y": 0 },
+ { "matrix": [1, 0], "x": 1, "y": 0 },
+ { "matrix": [0, 1], "x": 2, "y": 0 },
+ { "matrix": [1, 1], "x": 3, "y": 0 },
+ { "matrix": [0, 2], "x": 4, "y": 0 },
+ { "matrix": [1, 2], "x": 5, "y": 0 },
+ { "matrix": [0, 3], "x": 6, "y": 0 },
+ { "matrix": [1, 3], "x": 7, "y": 0 },
+ { "matrix": [0, 4], "x": 8, "y": 0 },
+ { "matrix": [1, 4], "x": 9, "y": 0 },
+ { "matrix": [0, 5], "x": 10, "y": 0 },
+ { "matrix": [1, 5], "x": 11, "y": 0 },
+ { "matrix": [0, 6], "x": 12, "y": 0 },
+ { "matrix": [1, 6], "x": 13, "y": 0 },
+ { "matrix": [0, 7], "x": 14.25, "y": 0 },
+ { "matrix": [1, 7], "x": 15.25, "y": 0 },
+ { "matrix": [0, 8], "x": 16.25, "y": 0 },
+ { "matrix": [1, 8], "x": 17.5, "y": 0 },
+ { "matrix": [0, 9], "x": 18.5, "y": 0 },
+ { "matrix": [1, 9], "x": 19.5, "y": 0 },
+ { "matrix": [0, 10], "x": 20.5, "y": 0 },
+ { "matrix": [2, 0], "x": 0, "y": 1 },
+ { "matrix": [3, 0], "x": 1, "y": 1 },
+ { "matrix": [2, 1], "x": 2, "y": 1 },
+ { "matrix": [3, 1], "x": 3, "y": 1 },
+ { "matrix": [2, 2], "x": 4, "y": 1 },
+ { "matrix": [3, 2], "x": 5, "y": 1 },
+ { "matrix": [2, 3], "x": 6, "y": 1 },
+ { "matrix": [3, 3], "x": 7, "y": 1 },
+ { "matrix": [2, 4], "x": 8, "y": 1 },
+ { "matrix": [3, 4], "x": 9, "y": 1 },
+ { "matrix": [2, 5], "x": 10, "y": 1 },
+ { "matrix": [3, 5], "x": 11, "y": 1 },
+ { "matrix": [2, 6], "x": 12, "y": 1 },
+ { "matrix": [3, 6], "x": 13, "y": 1 },
+ { "matrix": [2, 7], "x": 14.25, "y": 1 },
+ { "matrix": [3, 7], "x": 15.25, "y": 1 },
+ { "matrix": [2, 8], "x": 16.25, "y": 1 },
+ { "matrix": [3, 8], "x": 17.5, "y": 1 },
+ { "matrix": [2, 9], "x": 18.5, "y": 1 },
+ { "matrix": [3, 9], "x": 19.5, "y": 1 },
+ { "h": 2, "matrix": [5, 10], "x": 20.5, "y": 1 },
+ { "matrix": [4, 0], "x": 0, "y": 2 },
+ { "matrix": [5, 0], "x": 1, "y": 2 },
+ { "matrix": [4, 1], "x": 2, "y": 2 },
+ { "matrix": [5, 1], "x": 3, "y": 2 },
+ { "matrix": [4, 2], "x": 4, "y": 2 },
+ { "matrix": [5, 2], "x": 5, "y": 2 },
+ { "matrix": [4, 3], "x": 6, "y": 2 },
+ { "matrix": [5, 3], "x": 7, "y": 2 },
+ { "matrix": [4, 4], "x": 8, "y": 2 },
+ { "matrix": [5, 4], "x": 9, "y": 2 },
+ { "matrix": [4, 5], "x": 10, "y": 2 },
+ { "matrix": [5, 5], "x": 11, "y": 2 },
+ { "matrix": [4, 6], "x": 12, "y": 2 },
+ { "matrix": [5, 6], "x": 13, "y": 2 },
+ { "matrix": [5, 9], "x": 17.5, "y": 2 },
+ { "matrix": [4, 9], "x": 18.5, "y": 2 },
+ { "matrix": [4, 10], "x": 19.5, "y": 2 },
+ { "matrix": [6, 0], "w": 2, "x": 0, "y": 3 },
+ { "matrix": [7, 0], "x": 2, "y": 3 },
+ { "matrix": [6, 2], "x": 3, "y": 3 },
+ { "matrix": [7, 2], "x": 4, "y": 3 },
+ { "matrix": [6, 3], "x": 5, "y": 3 },
+ { "matrix": [7, 3], "x": 6, "y": 3 },
+ { "matrix": [6, 4], "x": 7, "y": 3 },
+ { "matrix": [7, 4], "x": 8, "y": 3 },
+ { "matrix": [6, 5], "x": 9, "y": 3 },
+ { "matrix": [7, 5], "x": 10, "y": 3 },
+ { "matrix": [7, 6], "x": 11, "y": 3 },
+ { "matrix": [6, 6], "w": 2, "x": 12, "y": 3 },
+ { "matrix": [6, 8], "x": 15.25, "y": 3 },
+ { "matrix": [7, 8], "x": 17.5, "y": 3 },
+ { "matrix": [6, 9], "x": 18.5, "y": 3 },
+ { "matrix": [7, 9], "x": 19.5, "y": 3 },
+ { "h": 2, "matrix": [9, 10], "x": 20.5, "y": 3 },
+ { "matrix": [8, 0], "w": 1.25, "x": 0, "y": 4 },
+ { "matrix": [9, 0], "x": 1.25, "y": 4 },
+ { "matrix": [8, 1], "w": 1.25, "x": 2.25, "y": 4 },
+ { "matrix": [8, 4], "w": 7, "x": 3.5, "y": 4 },
+ { "matrix": [9, 4], "w": 1.25, "x": 10.5, "y": 4 },
+ { "matrix": [8, 6], "x": 11.75, "y": 4 },
+ { "matrix": [9, 6], "w": 1.25, "x": 12.75, "y": 4 },
+ { "matrix": [8, 7], "x": 14.25, "y": 4 },
+ { "matrix": [9, 7], "x": 15.25, "y": 4 },
+ { "matrix": [8, 8], "x": 16.25, "y": 4 },
+ { "matrix": [9, 8], "w": 2, "x": 17.5, "y": 4 },
+ { "matrix": [8, 10], "x": 19.5, "y": 4 }
+ ]
+ }
+ }
+}
diff --git a/keyboards/keyten/ortho_slayer/keymaps/default/keymap.c b/keyboards/keyten/ortho_slayer/keymaps/default/keymap.c
new file mode 100644
index 00000000000..ea471d31efc
--- /dev/null
+++ b/keyboards/keyten/ortho_slayer/keymaps/default/keymap.c
@@ -0,0 +1,24 @@
+// Copyright 2025 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [0] = LAYOUT(
+ MO(1), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_GRV, KC_INS, KC_HOME, KC_PGUP, KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
+ KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, KC_DEL, KC_END, KC_PGDN, KC_P7, KC_P8, KC_KP_9, KC_PPLS,
+ KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_BSLS, KC_ENT, KC_P4, KC_P5, KC_P6,
+ 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_P1, KC_P2, KC_P3, KC_PENT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT
+ ),
+
+ [1] = 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, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+ )
+
+};
diff --git a/keyboards/keyten/ortho_slayer/readme.md b/keyboards/keyten/ortho_slayer/readme.md
new file mode 100644
index 00000000000..bae4adf3b6c
--- /dev/null
+++ b/keyboards/keyten/ortho_slayer/readme.md
@@ -0,0 +1,27 @@
+# keyten x La-Versa Ortho Slayer
+
+Ortho Slayer is a full size FRL ortho keyboard inspired by Berserk
+
+
+
+* Keyboard Maintainer: [keyten](https://github.com/key10iq)
+* Hardware Supported: keyten x La-Versa Ortho Slayer
+* Hardware Availability: private GB
+
+Make example for this keyboard (after setting up your build environment):
+
+ make keyten/ortho_slayer:default
+
+Flashing example for this keyboard:
+
+ make keyten/ortho_slayer:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* Bootmagic reset: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
+* Keycode in layout: Press the key mapped to `QK_BOOT` if it is available
+* Physical reset button: Hold the button on the back of the PCB
diff --git a/keyboards/kradoindustries/promenade/keyboard.json b/keyboards/kradoindustries/promenade/keyboard.json
index 028ba1b24df..1de6ef73156 100644
--- a/keyboards/kradoindustries/promenade/keyboard.json
+++ b/keyboards/kradoindustries/promenade/keyboard.json
@@ -201,6 +201,81 @@
{"matrix": [4, 13], "x":13.5, "y":4, "w":1.5}
]
},
+ "LAYOUT_1x2u": {
+ "layout": [
+ {"matrix": [0, 0], "x":0, "y":0, "w":1.5},
+ {"matrix": [0, 1], "x":1.5, "y":0},
+ {"matrix": [0, 2], "x":2.5, "y":0},
+ {"matrix": [0, 3], "x":3.5, "y":0},
+ {"matrix": [0, 4], "x":4.5, "y":0},
+ {"matrix": [0, 5], "x":5.5, "y":0},
+ {"matrix": [0, 6], "x":6.5, "y":0},
+ {"matrix": [0, 7], "x":7.5, "y":0},
+ {"matrix": [0, 8], "x":8.5, "y":0},
+ {"matrix": [0, 9], "x":9.5, "y":0},
+ {"matrix": [0, 10], "x":10.5, "y":0},
+ {"matrix": [0, 11], "x":11.5, "y":0},
+ {"matrix": [0, 12], "x":12.5, "y":0},
+ {"matrix": [0, 13], "x":13.5, "y":0, "w":1.5},
+
+ {"matrix": [1, 0], "x":0, "y":1, "w":1.5},
+ {"matrix": [1, 1], "x":1.5, "y":1},
+ {"matrix": [1, 2], "x":2.5, "y":1},
+ {"matrix": [1, 3], "x":3.5, "y":1},
+ {"matrix": [1, 4], "x":4.5, "y":1},
+ {"matrix": [1, 5], "x":5.5, "y":1},
+ {"matrix": [1, 6], "x":6.5, "y":1, "h":1.5},
+ {"matrix": [1, 7], "x":7.5, "y":1, "h":1.5},
+ {"matrix": [1, 8], "x":8.5, "y":1},
+ {"matrix": [1, 9], "x":9.5, "y":1},
+ {"matrix": [1, 10], "x":10.5, "y":1},
+ {"matrix": [1, 11], "x":11.5, "y":1},
+ {"matrix": [1, 12], "x":12.5, "y":1},
+ {"matrix": [1, 13], "x":13.5, "y":1, "w":1.5},
+
+ {"matrix": [2, 0], "x":0, "y":2, "w":1.5},
+ {"matrix": [2, 1], "x":1.5, "y":2},
+ {"matrix": [2, 2], "x":2.5, "y":2},
+ {"matrix": [2, 3], "x":3.5, "y":2},
+ {"matrix": [2, 4], "x":4.5, "y":2},
+ {"matrix": [2, 5], "x":5.5, "y":2},
+ {"matrix": [2, 8], "x":8.5, "y":2},
+ {"matrix": [2, 9], "x":9.5, "y":2},
+ {"matrix": [2, 10], "x":10.5, "y":2},
+ {"matrix": [2, 11], "x":11.5, "y":2},
+ {"matrix": [2, 12], "x":12.5, "y":2},
+ {"matrix": [2, 13], "x":13.5, "y":2, "w":1.5},
+
+ {"matrix": [3, 0], "x":0, "y":3, "w":1.5},
+ {"matrix": [3, 1], "x":1.5, "y":3},
+ {"matrix": [3, 2], "x":2.5, "y":3},
+ {"matrix": [3, 3], "x":3.5, "y":3},
+ {"matrix": [3, 4], "x":4.5, "y":3},
+ {"matrix": [3, 5], "x":5.5, "y":3},
+ {"matrix": [3, 6], "x":6.5, "y":2.5, "h":1.5},
+ {"matrix": [3, 7], "x":7.5, "y":2.5, "h":1.5},
+ {"matrix": [3, 8], "x":8.5, "y":3},
+ {"matrix": [3, 9], "x":9.5, "y":3},
+ {"matrix": [3, 10], "x":10.5, "y":3},
+ {"matrix": [3, 11], "x":11.5, "y":3},
+ {"matrix": [3, 12], "x":12.5, "y":3},
+ {"matrix": [3, 13], "x":13.5, "y":3, "w":1.5},
+
+ {"matrix": [4, 0], "x":0, "y":4, "w":1.5},
+ {"matrix": [4, 1], "x":1.5, "y":4},
+ {"matrix": [4, 2], "x":2.5, "y":4},
+ {"matrix": [4, 3], "x":3.5, "y":4},
+ {"matrix": [4, 4], "x":4.5, "y":4},
+ {"matrix": [4, 5], "x":5.5, "y":4},
+ {"matrix": [4, 6], "x":6.5, "y":4, "w":2},
+ {"matrix": [4, 8], "x":8.5, "y":4},
+ {"matrix": [4, 9], "x":9.5, "y":4},
+ {"matrix": [4, 10], "x":10.5, "y":4},
+ {"matrix": [4, 11], "x":11.5, "y":4},
+ {"matrix": [4, 12], "x":12.5, "y":4},
+ {"matrix": [4, 13], "x":13.5, "y":4, "w":1.5}
+ ]
+ },
"LAYOUT_2x3u": {
"layout": [
{"matrix": [0, 0], "x":0, "y":0, "w":1.5},
diff --git a/keyboards/phdesign/ph60/multi/keyboard.json b/keyboards/phdesign/ph60/multi/keyboard.json
new file mode 100644
index 00000000000..7240974f70c
--- /dev/null
+++ b/keyboards/phdesign/ph60/multi/keyboard.json
@@ -0,0 +1,298 @@
+{
+ "manufacturer": "phdesign.cc",
+ "keyboard_name": "ph60_multi",
+ "maintainer": "phdesign",
+ "bootloader": "rp2040",
+ "diode_direction": "COL2ROW",
+ "features": {
+ "bootmagic": true,
+ "extrakey": true,
+ "mousekey": true,
+ "nkro": true
+ },
+ "matrix_pins": {
+ "cols": ["GP0", "GP1", "GP2", "GP3", "GP4", "GP5", "GP6", "GP7", "GP8", "GP9", "GP10", "GP11", "GP12", "GP13"],
+ "rows": ["GP14", "GP15", "GP18", "GP19", "GP20"]
+ },
+ "processor": "RP2040",
+ "qmk": {
+ "locking": {
+ "enabled": true,
+ "resync": true
+ }
+ },
+ "url": "phdesign.cc",
+ "usb": {
+ "device_version": "2.0.1",
+ "pid": "0x0002",
+ "vid": "0x5048"
+ },
+ "community_layouts": ["60_ansi", "60_ansi_tsangan_split_bs_rshift", "60_iso"]
+ "layouts": {
+ "LAYOUT_all": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [2, 13], "x": 14, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 12], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 1.25},
+ {"matrix": [3, 1], "x": 1.25, "y": 3},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 13], "x": 14, "y": 3},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25}
+ ]
+ },
+ "LAYOUT_60_ansi": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0, "w": 2},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 12], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 2.75},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25}
+ ]
+ },
+ "LAYOUT_60_ansi_tsangan_split_bs_rshift": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [2, 13], "x": 14, "y": 0},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [1, 13], "x": 13.5, "y": 1, "w": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [2, 12], "x": 12.75, "y": 2, "w": 2.25},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 13], "x": 14, "y": 3},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.5},
+ {"matrix": [4, 1], "x": 1.5, "y": 4},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.5},
+ {"matrix": [4, 6], "x": 4, "y": 4, "w": 7},
+ {"matrix": [4, 11], "x": 11, "y": 4, "w": 1.5},
+ {"matrix": [4, 12], "x": 12.5, "y": 4},
+ {"matrix": [4, 13], "x": 13.5, "y": 4, "w": 1.5}
+ ]
+ },
+ "LAYOUT_60_iso": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0, "w": 2},
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 1], "x": 1.5, "y": 1},
+ {"matrix": [1, 2], "x": 2.5, "y": 1},
+ {"matrix": [1, 3], "x": 3.5, "y": 1},
+ {"matrix": [1, 4], "x": 4.5, "y": 1},
+ {"matrix": [1, 5], "x": 5.5, "y": 1},
+ {"matrix": [1, 6], "x": 6.5, "y": 1},
+ {"matrix": [1, 7], "x": 7.5, "y": 1},
+ {"matrix": [1, 8], "x": 8.5, "y": 1},
+ {"matrix": [1, 9], "x": 9.5, "y": 1},
+ {"matrix": [1, 10], "x": 10.5, "y": 1},
+ {"matrix": [1, 11], "x": 11.5, "y": 1},
+ {"matrix": [1, 12], "x": 12.5, "y": 1},
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 1], "x": 1.75, "y": 2},
+ {"matrix": [2, 2], "x": 2.75, "y": 2},
+ {"matrix": [2, 3], "x": 3.75, "y": 2},
+ {"matrix": [2, 4], "x": 4.75, "y": 2},
+ {"matrix": [2, 5], "x": 5.75, "y": 2},
+ {"matrix": [2, 6], "x": 6.75, "y": 2},
+ {"matrix": [2, 7], "x": 7.75, "y": 2},
+ {"matrix": [2, 8], "x": 8.75, "y": 2},
+ {"matrix": [2, 9], "x": 9.75, "y": 2},
+ {"matrix": [2, 10], "x": 10.75, "y": 2},
+ {"matrix": [2, 11], "x": 11.75, "y": 2},
+ {"matrix": [1, 13], "x": 12.75, "y": 2},
+ {"matrix": [2, 12], "x": 13.75, "y": 1, "w": 1.25, "h": 2},
+ {"matrix": [3, 0], "x": 0, "y": 3, "w": 1.25},
+ {"matrix": [3, 1], "x": 1.25, "y": 3},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 12], "x": 12.25, "y": 3, "w": 2.75},
+ {"matrix": [4, 0], "x": 0, "y": 4, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4, "w": 1.25},
+ {"matrix": [4, 12], "x": 12.5, "y": 4, "w": 1.25},
+ {"matrix": [4, 13], "x": 13.75, "y": 4, "w": 1.25}
+ ]
+ }
+ }
+}
diff --git a/keyboards/phdesign/ph60/multi/keymaps/default/keymap.c b/keyboards/phdesign/ph60/multi/keymaps/default/keymap.c
new file mode 100644
index 00000000000..74d7a97299c
--- /dev/null
+++ b/keyboards/phdesign/ph60/multi/keymaps/default/keymap.c
@@ -0,0 +1,28 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+enum custom_layers {
+ _BASE,
+ _FN1,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+// Base Layer (61 keys)
+ [_BASE] = LAYOUT_all(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, _______,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(_FN1), KC_RCTL
+ ),
+ // Fn1 Layer (Windows Lock Shifting Layer)
+ [_FN1] = LAYOUT_all(
+ KC_GRV, 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_UP, _______, _______, _______, _______, _______, KC_INS, _______, KC_PSCR, KC_SCRL, KC_PAUS, _______,
+ _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGUP, _______,
+ _______, _______, _______, _______, _______, _______, _______, KC_VOLD, KC_VOLU, KC_MUTE, KC_END, KC_PGDN, _______, _______,
+ _______, GU_TOGG, _______, _______, _______, _______, _______, _______
+ ),
+};
diff --git a/keyboards/phdesign/ph60/multi/readme.md b/keyboards/phdesign/ph60/multi/readme.md
new file mode 100644
index 00000000000..320e8ec926f
--- /dev/null
+++ b/keyboards/phdesign/ph60/multi/readme.md
@@ -0,0 +1,28 @@
+# phdesign/ph60/multi
+
+
+
+A 60% multi-layout supported keyboard PCB with open source keyboard case.
+
+* Keyboard Maintainer: [Team PHDesign](https://github.com/ph-design)
+* Hardware Supported: PH60/Multi PCB
+* Hardware Availability:
+ - Store: https://e.tb.cn/h.6VMjUgWZkUGwq26?tk=oVyAeD6uPS2
+ - GitHub Repo: https://github.com/ph-design/PH60/tree/Rev.2/PCB_Rev2/Multi
+
+Make example for this keyboard (after setting up your build environment):
+
+ make phdesign/ph60/multi:default
+
+Flashing example for this keyboard:
+
+ make phdesign/ph60/multi:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
+* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
diff --git a/keyboards/phdesign/readme.md b/keyboards/phdesign/readme.md
new file mode 100644
index 00000000000..4605afc13ff
--- /dev/null
+++ b/keyboards/phdesign/readme.md
@@ -0,0 +1,9 @@
+
+
+PHDesign is a team focused on making variety kinds of tech stuff,including keyboards and keyboard-like controllers. This directory includes QMK config files for our keyboard products.
+
+* Maintainer: [Team PHDesign](https://github.com/ph-design)
+* Supported Hardware:
+ * [`PH60/Multi`](ph60/multi/): PH60 multi-layout PCB
+ * [`PH-AC`](phac/): PH-AC rhythm game controller
+* Product Availability: [phdesing.cc](https://phdesign.cc/)
diff --git a/keyboards/preonic/config.h b/keyboards/preonic/config.h
index c47b9e7ed42..67ff77912c4 100644
--- a/keyboards/preonic/config.h
+++ b/keyboards/preonic/config.h
@@ -20,6 +20,8 @@ along with this program. If not, see .
#define AUDIO_VOICES
#define AUDIO_PIN C6
+#define AUDIO_INIT_DELAY
+
/*
* Feature disable options
* These options are also useful to firmware size reduction.
diff --git a/keyboards/rubi/lib/calc.c b/keyboards/rubi/lib/calc.c
index 7796a9be451..b289fdb54bf 100644
--- a/keyboards/rubi/lib/calc.c
+++ b/keyboards/rubi/lib/calc.c
@@ -13,6 +13,7 @@ This is the modified version of [calculator by MWWorks](https://github.com/MWWor
Feel free to fix it! I think it needs to detect the precision of the two operands and then figure out what the precision of the result should be
*/
+#include
#include "rubi.h"
static uint8_t calc_current_operand = 0;
diff --git a/keyboards/shuguet/shu89/keyboard.json b/keyboards/shuguet/shu89/keyboard.json
index 072734b5440..c3e0d0e61a4 100644
--- a/keyboards/shuguet/shu89/keyboard.json
+++ b/keyboards/shuguet/shu89/keyboard.json
@@ -217,34 +217,34 @@
{"matrix": [0, 8], "x": 80, "y": 0, "flags": 4},
{"matrix": [0, 9], "x": 104, "y": 0, "flags": 4},
- {"matrix": [1, 4], "x": 16, "y": 13, "flags": 4},
+ {"matrix": [1, 4], "x": 0, "y": 13, "flags": 4},
+ {"matrix": [2, 4], "x": 20, "y": 13, "flags": 4},
{"matrix": [1, 5], "x": 32, "y": 13, "flags": 4},
{"matrix": [1, 6], "x": 48, "y": 13, "flags": 4},
{"matrix": [1, 7], "x": 64, "y": 13, "flags": 4},
{"matrix": [1, 8], "x": 80, "y": 13, "flags": 4},
{"matrix": [1, 9], "x": 96, "y": 13, "flags": 4},
- {"matrix": [2, 4], "x": 0, "y": 13, "flags": 4},
-
+
+ {"matrix": [3, 4], "x": 0, "y": 26, "flags": 4},
{"matrix": [2, 5], "x": 20, "y": 26, "flags": 4},
{"matrix": [2, 6], "x": 36, "y": 26, "flags": 4},
{"matrix": [2, 7], "x": 52, "y": 26, "flags": 4},
{"matrix": [2, 8], "x": 68, "y": 26, "flags": 4},
{"matrix": [2, 9], "x": 84, "y": 26, "flags": 4},
- {"matrix": [3, 4], "x": 0, "y": 26, "flags": 4},
+ {"matrix": [4, 4], "x": 0, "y": 39, "flags": 5},
{"matrix": [3, 5], "x": 24, "y": 39, "flags": 4},
{"matrix": [3, 6], "x": 40, "y": 39, "flags": 4},
{"matrix": [3, 7], "x": 56, "y": 39, "flags": 4},
{"matrix": [3, 8], "x": 72, "y": 39, "flags": 4},
{"matrix": [3, 9], "x": 88, "y": 39, "flags": 4},
- {"matrix": [4, 4], "x": 0, "y": 39, "flags": 5},
+ {"matrix": [5, 4], "x": 0, "y": 51, "flags": 5},
{"matrix": [4, 5], "x": 28, "y": 51, "flags": 4},
{"matrix": [4, 6], "x": 44, "y": 51, "flags": 4},
{"matrix": [4, 7], "x": 60, "y": 51, "flags": 4},
{"matrix": [4, 8], "x": 76, "y": 51, "flags": 4},
{"matrix": [4, 9], "x": 92, "y": 51, "flags": 4},
- {"matrix": [5, 4], "x": 0, "y": 51, "flags": 5},
{"matrix": [5, 5], "x": 0, "y": 64, "flags": 5},
{"matrix": [5, 6], "x": 20, "y": 64, "flags": 5},
@@ -274,6 +274,7 @@
{"matrix": [7, 8], "x": 220, "y": 13, "flags": 4},
{"matrix": [7, 9], "x": 224, "y": 13, "flags": 4},
+ {"matrix": [9, 0], "x": 100, "y": 26, "flags": 4},
{"matrix": [8, 0], "x": 116, "y": 26, "flags": 4},
{"matrix": [8, 1], "x": 132, "y": 26, "flags": 4},
{"matrix": [8, 2], "x": 148, "y": 26, "flags": 4},
@@ -284,23 +285,22 @@
{"matrix": [8, 7], "x": 216, "y": 26, "flags": 4},
{"matrix": [8, 8], "x": 220, "y": 26, "flags": 4},
{"matrix": [8, 9], "x": 224, "y": 26, "flags": 4},
- {"matrix": [9, 0], "x": 100, "y": 26, "flags": 4},
-
+
+ {"matrix": [10, 0], "x": 104, "y": 39, "flags": 4},
{"matrix": [9, 1], "x": 120, "y": 39, "flags": 4},
{"matrix": [9, 2], "x": 136, "y": 39, "flags": 4},
{"matrix": [9, 3], "x": 152, "y": 39, "flags": 4},
{"matrix": [9, 4], "x": 168, "y": 39, "flags": 4},
{"matrix": [9, 5], "x": 184, "y": 39, "flags": 4},
{"matrix": [9, 6], "x": 200, "y": 39, "flags": 4},
- {"matrix": [10, 0], "x": 104, "y": 39, "flags": 4},
-
+
+ {"matrix": [11, 0], "x": 108, "y": 51, "flags": 4},
{"matrix": [10, 1], "x": 124, "y": 51, "flags": 4},
{"matrix": [10, 2], "x": 140, "y": 51, "flags": 4},
{"matrix": [10, 3], "x": 156, "y": 51, "flags": 4},
{"matrix": [10, 4], "x": 172, "y": 51, "flags": 4},
{"matrix": [10, 6], "x": 188, "y": 51, "flags": 5},
{"matrix": [10, 8], "x": 216, "y": 51, "flags": 4},
- {"matrix": [11, 0], "x": 108, "y": 51, "flags": 4},
{"matrix": [11, 1], "x": 118, "y": 64, "flags": 4},
{"matrix": [11, 3], "x": 144, "y": 64, "flags": 5},
diff --git a/keyboards/suikagiken/suika83opti/keyboard.json b/keyboards/suikagiken/suika83opti/keyboard.json
new file mode 100644
index 00000000000..d9876434fe1
--- /dev/null
+++ b/keyboards/suikagiken/suika83opti/keyboard.json
@@ -0,0 +1,115 @@
+{
+ "manufacturer": "suikagiken",
+ "keyboard_name": "suika83opti",
+ "maintainer": "suikagiken",
+ "processor": "RP2040",
+ "bootloader": "rp2040",
+ "diode_direction": "COL2ROW",
+ "features": {
+ "bootmagic": true,
+ "command": false,
+ "console": false,
+ "extrakey": true,
+ "mousekey": true,
+ "nkro": true
+ },
+ "matrix_pins": {
+ "cols": ["GP0", "GP1", "GP2", "GP3", "GP4", "GP5", "GP6", "GP7", "GP8", "GP9", "GP10", "GP11", "GP12", "GP13", "GP14", "GP15"],
+ "rows": ["GP29", "GP28", "GP27", "GP26", "GP25", "GP24"]
+ },
+ "url": "https://github.com/suikagiken/suika83opti",
+ "usb": {
+ "device_version": "1.0.0",
+ "vid": "0x4B48",
+ "pid": "0x0101"
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"matrix": [0,0], "x": 0, "y": 0},
+ {"matrix": [0,1], "x": 1.5, "y": 0},
+ {"matrix": [0,2], "x": 2.5, "y": 0},
+ {"matrix": [0,3], "x": 3.5, "y": 0},
+ {"matrix": [0,4], "x": 4.5, "y": 0},
+ {"matrix": [0,5], "x": 7, "y": 0},
+ {"matrix": [0,6], "x": 8, "y": 0},
+ {"matrix": [0,8], "x": 9, "y": 0},
+ {"matrix": [0,9], "x": 10, "y": 0},
+ {"matrix": [0,10], "x": 12.75, "y": 0},
+ {"matrix": [0,11], "x": 13.75, "y": 0},
+ {"matrix": [0,12], "x": 14.75, "y": 0},
+ {"matrix": [0,13], "x": 15.75, "y": 0},
+ {"matrix": [0,15], "x": 17.25, "y": 0},
+ {"matrix": [1,0], "x": 0, "y": 1.5},
+ {"matrix": [1,1], "x": 1, "y": 1.5},
+ {"matrix": [1,2], "x": 2, "y": 1.5},
+ {"matrix": [1,3], "x": 3, "y": 1.5},
+ {"matrix": [1,4], "x": 4, "y": 1.5},
+ {"matrix": [1,5], "x": 5, "y": 1.5},
+ {"matrix": [1,6], "x": 6, "y": 1.5},
+ {"matrix": [1,7], "x": 8.5, "y": 1.5},
+ {"matrix": [1,9], "x": 11.5, "y": 1.5},
+ {"matrix": [1,10], "x": 12.5, "y": 1.5},
+ {"matrix": [1,11], "x": 13.5, "y": 1.5},
+ {"matrix": [1,12], "x": 14.5, "y": 1.5},
+ {"matrix": [1,13], "x": 15.5, "y": 1.5},
+ {"matrix": [1,15], "x": 17.25, "y": 1.5, "h": 1.5},
+ {"matrix": [2,0], "x": 0, "y": 2.5, "w": 1.5},
+ {"matrix": [2,1], "x": 1.5, "y": 2.5},
+ {"matrix": [2,2], "x": 2.5, "y": 2.5},
+ {"matrix": [2,3], "x": 3.5, "y": 2.5},
+ {"matrix": [2,4], "x": 4.5, "y": 2.5},
+ {"matrix": [2,5], "x": 5.5, "y": 2.5},
+ {"matrix": [2,7], "x": 8.5, "y": 2.5},
+ {"matrix": [2,9], "x": 11, "y": 2.5},
+ {"matrix": [2,10], "x": 12, "y": 2.5},
+ {"matrix": [2,11], "x": 13, "y": 2.5},
+ {"matrix": [2,12], "x": 14, "y": 2.5},
+ {"matrix": [2,13], "x": 15, "y": 2.5},
+ {"matrix": [2,14], "x": 16, "y": 2.5},
+ {"matrix": [3,0], "x": 0.25, "y": 3.5, "w": 1.5},
+ {"matrix": [3,1], "x": 1.75, "y": 3.5},
+ {"matrix": [3,2], "x": 2.75, "y": 3.5},
+ {"matrix": [3,3], "x": 3.75, "y": 3.5},
+ {"matrix": [3,4], "x": 4.75, "y": 3.5},
+ {"matrix": [3,5], "x": 5.75, "y": 3.5},
+ {"matrix": [3,6], "x": 8, "y": 3.5},
+ {"matrix": [3,8], "x": 9, "y": 3.5},
+ {"matrix": [3,9], "x": 11.25, "y": 3.5},
+ {"matrix": [3,10], "x": 12.25, "y": 3.5},
+ {"matrix": [3,11], "x": 13.25, "y": 3.5},
+ {"matrix": [3,12], "x": 14.25, "y": 3.5},
+ {"matrix": [3,13], "x": 15.25, "y": 3.5},
+ {"matrix": [3,14], "x": 16.25, "y": 3.5},
+ {"matrix": [3,15], "x": 17.25, "y": 3, "h": 1.5},
+ {"matrix": [4,0], "x": 0.75, "y": 4.5, "w": 1.5},
+ {"matrix": [4,1], "x": 2.25, "y": 4.5},
+ {"matrix": [4,2], "x": 3.25, "y": 4.5},
+ {"matrix": [4,3], "x": 4.25, "y": 4.5},
+ {"matrix": [4,4], "x": 5.25, "y": 4.5},
+ {"matrix": [4,5], "x": 6.25, "y": 4.5},
+ {"matrix": [4,7], "x": 8.5, "y": 4.5},
+ {"matrix": [4,9], "x": 10.75, "y": 4.5},
+ {"matrix": [4,10], "x": 11.75, "y": 4.5},
+ {"matrix": [4,11], "x": 12.75, "y": 4.5},
+ {"matrix": [4,12], "x": 13.75, "y": 4.5},
+ {"matrix": [4,13], "x": 14.75, "y": 4.5},
+ {"matrix": [4,14], "x": 15.75, "y": 4.5},
+ {"matrix": [4,15], "x": 16.75, "y": 4.5},
+ {"matrix": [5,0], "x": 1.25, "y": 5.5, "w": 1.5},
+ {"matrix": [5,1], "x": 2.75, "y": 5.5},
+ {"matrix": [5,2], "x": 3.75, "y": 5.5},
+ {"matrix": [5,3], "x": 4.75, "y": 5.5},
+ {"matrix": [5,4], "x": 5.75, "y": 5.5, "w": 1.5},
+ {"matrix": [5,6], "x": 7.5, "y": 5.5},
+ {"matrix": [5,7], "x": 8.5, "y": 5.5},
+ {"matrix": [5,8], "x": 9.5, "y": 5.5},
+ {"matrix": [5,9], "x": 10.75, "y": 5.5, "w": 1.5},
+ {"matrix": [5,10], "x": 12.25, "y": 5.5},
+ {"matrix": [5,11], "x": 13.25, "y": 5.5},
+ {"matrix": [5,12], "x": 14.25, "y": 5.5},
+ {"matrix": [5,13], "x": 15.25, "y": 5.5, "w": 1.5}
+ ]
+ }
+ }
+}
diff --git a/keyboards/suikagiken/suika83opti/keymaps/default/keymap.json b/keyboards/suikagiken/suika83opti/keymaps/default/keymap.json
new file mode 100644
index 00000000000..8434463eb8f
--- /dev/null
+++ b/keyboards/suikagiken/suika83opti/keymaps/default/keymap.json
@@ -0,0 +1,24 @@
+{
+ "author": "suikagiken",
+ "keyboard": "suikagiken/suika83opti",
+ "keymap": "default",
+ "layout": "LAYOUT",
+ "layers": [
+ [
+ "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_DEL" ,
+ "KC_GRV" , "KC_1" , "KC_2" , "KC_3" , "KC_4" , "KC_5" , "KC_6" , "KC_PSCR", "KC_7" , "KC_8" , "KC_9" , "KC_0" , "KC_MINS", "KC_BSPC",
+ "KC_TAB" , "KC_Q" , "KC_W" , "KC_E" , "KC_R" , "KC_T" , "KC_EQL" , "KC_Y" , "KC_U" , "KC_I" , "KC_O" , "KC_P" , "KC_BSLS",
+ "KC_CAPS", "KC_A" , "KC_S" , "KC_D" , "KC_F" , "KC_G" , "KC_LBRC", "KC_RBRC", "KC_H" , "KC_J" , "KC_K" , "KC_L" , "KC_SCLN", "KC_QUOT", "KC_ENT" ,
+ "KC_LSFT", "KC_Z" , "KC_X" , "KC_C" , "KC_V" , "KC_B" , "KC_UP" , "KC_B" , "KC_N" , "KC_M" , "KC_COMM", "KC_DOT" , "KC_SLSH", "KC_RSFT",
+ "KC_LCTL", "KC_LWIN", "KC_LOPT", "MO(1)" , "KC_SPC" , "KC_LEFT", "KC_DOWN", "KC_RGHT", "KC_SPC" , "MO(1)" , "KC_ROPT", "KC_APP" , "KC_RCTL"
+ ],
+ [
+ "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
+ "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
+ "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
+ "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
+ "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_PGUP", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS",
+ "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_HOME", "KC_PGDN", "KC_END" , "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"
+ ]
+ ]
+}
diff --git a/keyboards/suikagiken/suika83opti/readme.md b/keyboards/suikagiken/suika83opti/readme.md
new file mode 100644
index 00000000000..cbd83950873
--- /dev/null
+++ b/keyboards/suikagiken/suika83opti/readme.md
@@ -0,0 +1,43 @@
+# suika83opti
+(English Follows Japanese)
+
+## 概要
+
+
+
+suika83optiはロースタッガードの一体型エルゴキーボードです。
+ファンクションキーや矢印キーなど、コンパクトキーボードでは省略されがちなキーも備えており、フルキーボードからの移行も容易です。
+
+* 制作 : すいか技研 (Website: https://suikagiken.net GitHub: [suikagiken](https://github.com/suikagiken) )
+* 販売 : すいか技研の[booth](https://suikagiken.booth.pm/)にて販売予定です
+
+## ビルドガイド
+
+[こちら](https://github.com/suikagiken/suika83opti/blob/main/buildguide_1.0.md)からご覧下さい。
+
+---
+
+## Overview
+
+suika83opti is a row-staggered ergonomic keyboard with 85 keys. It has function keys or arrow keys, which are omitted in compact keyboards, making it easy to switch from a conventional full keyboard.
+
+* Keyboard Maintainer: [suikagiken](https://github.com/suikagiken)
+* Hardware Availability: Available at [booth](https://suikagiken.booth.pm/).
+
+Make example for this keyboard (after setting up your build environment):
+
+ make suikagiken/suika83opti:default
+
+Flashing example for this keyboard:
+
+ make suikagiken/suika83opti:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
+* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
+* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
diff --git a/keyboards/terrazzo/terrazzo.c b/keyboards/terrazzo/terrazzo.c
index 2a3d2a8cc61..a629e5dceb3 100644
--- a/keyboards/terrazzo/terrazzo.c
+++ b/keyboards/terrazzo/terrazzo.c
@@ -14,6 +14,7 @@
* along with this program. If not, see .
*/
+#include
#include "terrazzo.h"
#ifdef LED_MATRIX_ENABLE
diff --git a/keyboards/tzarc/kobold/config.h b/keyboards/tzarc/kobold/config.h
new file mode 100644
index 00000000000..b3991ae0377
--- /dev/null
+++ b/keyboards/tzarc/kobold/config.h
@@ -0,0 +1,29 @@
+// Copyright 2025 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+// Hardware-specific definitions
+#define RGB_ENABLE_PIN C11
+
+// WS2812 Configuration
+#define WS2812_PWM_DRIVER PWMD17
+#define WS2812_PWM_CHANNEL 1
+#define WS2812_PWM_PAL_MODE 10
+#define WS2812_PWM_DMA_STREAM STM32_DMA1_STREAM1
+#define WS2812_PWM_DMA_CHANNEL 1
+#define WS2812_PWM_DMAMUX_ID STM32_DMAMUX1_TIM17_UP
+
+// SPI Configuration
+#define SPI_DRIVER SPID1
+#define SPI_SCK_PIN A5
+#define SPI_SCK_PAL_MODE 5
+#define SPI_MOSI_PIN A7
+#define SPI_MOSI_PAL_MODE 5
+#define SPI_MISO_PIN A6
+#define SPI_MISO_PAL_MODE 5
+
+// External NOR Flash config
+#define EXTERNAL_FLASH_SPI_MODE 0
+#define EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN B10
+#define EXTERNAL_FLASH_SPI_CLOCK_DIVISOR 4 // (160MHz/4) => 40MHz
+#define EXTERNAL_FLASH_SIZE (16 * 1024 * 1024) // 128Mb/16MB capacity
diff --git a/keyboards/tzarc/kobold/halconf.h b/keyboards/tzarc/kobold/halconf.h
new file mode 100644
index 00000000000..2251180c141
--- /dev/null
+++ b/keyboards/tzarc/kobold/halconf.h
@@ -0,0 +1,8 @@
+// Copyright 2025 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#define HAL_USE_PWM TRUE
+#define HAL_USE_SPI TRUE
+
+#include_next
diff --git a/keyboards/tzarc/kobold/info.json b/keyboards/tzarc/kobold/info.json
new file mode 100644
index 00000000000..bed8e8a23fe
--- /dev/null
+++ b/keyboards/tzarc/kobold/info.json
@@ -0,0 +1,82 @@
+{
+ "manufacturer": "Tzarc",
+ "keyboard_name": "Kobold",
+ "url": "https://github.com/tzarc/keyboards/tree/main/Kobold",
+ "maintainer": "tzarc",
+ "bootloader": "stm32-dfu",
+ "build": {
+ "lto": true
+ },
+ "dynamic_keymap": {
+ "layer_count": 32
+ },
+ "eeprom": {
+ "driver": "wear_leveling",
+ "wear_leveling": {
+ "backing_size": 32768,
+ "driver": "spi_flash"
+ }
+ },
+ "features": {
+ "bootmagic": true,
+ "rgb_matrix": true
+ },
+ "matrix_pins": {
+ "direct": [
+ ["B14", "C6", "B9", "B7", "B13", "B15", "C13", "C15", "B12", "B0", "A2", "A0", "B11", "A4", "A3", "A1"]
+ ]
+ },
+ "processor": "STM32G431",
+ "rgb_matrix": {
+ "driver": "ws2812",
+ "layout": [
+ {"x": 0, "y": 0, "flags": 2},
+ {"x": 75, "y": 0, "flags": 2},
+ {"x": 150, "y": 0, "flags": 2},
+ {"x": 224, "y": 0, "flags": 2},
+ {"x": 224, "y": 21, "flags": 2},
+ {"x": 150, "y": 21, "flags": 2},
+ {"x": 75, "y": 21, "flags": 2},
+ {"x": 0, "y": 21, "flags": 2},
+ {"x": 0, "y": 43, "flags": 2},
+ {"x": 75, "y": 43, "flags": 2},
+ {"x": 150, "y": 43, "flags": 2},
+ {"x": 224, "y": 43, "flags": 2},
+ {"x": 224, "y": 64, "flags": 2},
+ {"x": 150, "y": 64, "flags": 2},
+ {"x": 75, "y": 64, "flags": 2},
+ {"x": 0, "y": 64, "flags": 2}
+ ]
+ },
+ "usb": {
+ "pid": "0x4921",
+ "vid": "0x1209"
+ },
+ "ws2812": {
+ "driver": "pwm",
+ "pin": "B5"
+ },
+ "community_layouts": ["ortho_4x4"],
+ "layouts": {
+ "LAYOUT_ortho_4x4": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 0, "y": 1},
+ {"matrix": [0, 5], "x": 1, "y": 1},
+ {"matrix": [0, 6], "x": 2, "y": 1},
+ {"matrix": [0, 7], "x": 3, "y": 1},
+ {"matrix": [0, 8], "x": 0, "y": 2},
+ {"matrix": [0, 9], "x": 1, "y": 2},
+ {"matrix": [0, 10], "x": 2, "y": 2},
+ {"matrix": [0, 11], "x": 3, "y": 2},
+ {"matrix": [0, 12], "x": 0, "y": 3},
+ {"matrix": [0, 13], "x": 1, "y": 3},
+ {"matrix": [0, 14], "x": 2, "y": 3},
+ {"matrix": [0, 15], "x": 3, "y": 3}
+ ]
+ }
+ }
+}
diff --git a/keyboards/tzarc/kobold/keymaps/default/keymap.c b/keyboards/tzarc/kobold/keymaps/default/keymap.c
new file mode 100644
index 00000000000..d78325c78bb
--- /dev/null
+++ b/keyboards/tzarc/kobold/keymaps/default/keymap.c
@@ -0,0 +1,14 @@
+// Copyright 2025 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include QMK_KEYBOARD_H
+
+// clang-format off
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT_ortho_4x4(
+ KC_A, KC_B, KC_C, KC_D,
+ KC_E, KC_F, KC_G, KC_H,
+ KC_I, KC_J, KC_K, KC_L,
+ KC_M, KC_N, KC_O, KC_P
+ ),
+};
+// clang-format on
diff --git a/keyboards/tzarc/kobold/kobold.c b/keyboards/tzarc/kobold/kobold.c
new file mode 100644
index 00000000000..0460a4fe856
--- /dev/null
+++ b/keyboards/tzarc/kobold/kobold.c
@@ -0,0 +1,18 @@
+// Copyright 2025 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include QMK_KEYBOARD_H
+
+void early_hardware_init_post(void) {
+ // Disable RGB LEDs
+ gpio_set_pin_output(RGB_ENABLE_PIN);
+ gpio_write_pin(RGB_ENABLE_PIN, 1);
+}
+
+void housekeeping_task_kb() {
+ // Enable RGB LEDs after 200 milliseconds
+ static bool rgb_enabled = false;
+ if (!rgb_enabled && timer_read32() > 200) {
+ gpio_write_pin(RGB_ENABLE_PIN, 0);
+ rgb_enabled = true;
+ }
+}
diff --git a/keyboards/tzarc/kobold/mcuconf.h b/keyboards/tzarc/kobold/mcuconf.h
new file mode 100644
index 00000000000..5d7fdbe2322
--- /dev/null
+++ b/keyboards/tzarc/kobold/mcuconf.h
@@ -0,0 +1,12 @@
+// Copyright 2025 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+#include_next
+
+// Used for SK6812 chain
+#undef STM32_PWM_USE_TIM17
+#define STM32_PWM_USE_TIM17 TRUE
+
+// Used for NOR Flash
+#undef STM32_SPI_USE_SPI1
+#define STM32_SPI_USE_SPI1 TRUE
diff --git a/keyboards/tzarc/kobold/r1/keyboard.json b/keyboards/tzarc/kobold/r1/keyboard.json
new file mode 100644
index 00000000000..ad889c23048
--- /dev/null
+++ b/keyboards/tzarc/kobold/r1/keyboard.json
@@ -0,0 +1,5 @@
+{
+ "usb": {
+ "device_version": "1.0.0"
+ }
+}
diff --git a/keyboards/tzarc/kobold/readme.md b/keyboards/tzarc/kobold/readme.md
new file mode 100644
index 00000000000..0c73ed49e7d
--- /dev/null
+++ b/keyboards/tzarc/kobold/readme.md
@@ -0,0 +1,29 @@
+# Kobold
+
+
+
+4x4 macropad running QMK, in the same form factor as a bm16s. Non-standard Choc key spacing.
+
+North-facing RGB, SPI NOR Flash, voltage and current measurement, direct pin matrix, reset to bootloader by holding top 4 keys.
+
+* Keyboard Maintainer: [tzarc](https://github.com/tzarc)
+* Hardware Supported: Kobold, r1
+* Hardware Availability: [KiCad files](https://github.com/tzarc/keyboards/tree/main/Kobold)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make tzarc/kobold/r1:default
+
+Flashing example for this keyboard:
+
+ make tzarc/kobold/r1:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the top left key and plug in the keyboard
+* **Physical reset button**: Simultaneously press the top four keys, or press the physical button on the back marked 'D'.
+* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
diff --git a/keyboards/void/voidhhkb_hotswap/keyboard.json b/keyboards/void/voidhhkb_hotswap/keyboard.json
new file mode 100644
index 00000000000..460454cc5fb
--- /dev/null
+++ b/keyboards/void/voidhhkb_hotswap/keyboard.json
@@ -0,0 +1,97 @@
+{
+ "manufacturer": "James Wilson",
+ "keyboard_name": "voidhhkb_hotswap",
+ "maintainer": "JamesWilson1996",
+ "bootloader": "stm32-dfu",
+ "diode_direction": "COL2ROW",
+ "features": {
+ "bootmagic": true,
+ "command": false,
+ "console": false,
+ "extrakey": true,
+ "mousekey": true,
+ "nkro": true
+ },
+ "matrix_pins": {
+ "cols": ["B12", "B13", "A3", "A4", "B14", "B15", "A8", "A5", "A9", "A10", "A6", "A7", "A15", "B3", "B4"],
+ "rows": ["B11", "B10", "B2", "B1", "B0"]
+ },
+ "processor": "STM32F072",
+ "url": "",
+ "usb": {
+ "device_version": "1.0.0",
+ "pid": "0x0002",
+ "vid": "0x4A57"
+ },
+ "community_layouts": [ "60_hhkb" ],
+ "layouts": {
+ "LAYOUT_60_hhkb": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1, "y": 0},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0},
+ {"matrix": [0, 5], "x": 5, "y": 0},
+ {"matrix": [0, 6], "x": 6, "y": 0},
+ {"matrix": [0, 7], "x": 7, "y": 0},
+ {"matrix": [0, 8], "x": 8, "y": 0},
+ {"matrix": [0, 9], "x": 9, "y": 0},
+ {"matrix": [0, 10], "x": 10, "y": 0},
+ {"matrix": [0, 11], "x": 11, "y": 0},
+ {"matrix": [0, 12], "x": 12, "y": 0},
+ {"matrix": [0, 13], "x": 13, "y": 0},
+ {"matrix": [0, 14], "x": 14, "y": 0},
+
+ {"matrix": [1, 0], "x": 0, "y": 1, "w": 1.5},
+ {"matrix": [1, 2], "x": 1.5, "y": 1},
+ {"matrix": [1, 3], "x": 2.5, "y": 1},
+ {"matrix": [1, 4], "x": 3.5, "y": 1},
+ {"matrix": [1, 5], "x": 4.5, "y": 1},
+ {"matrix": [1, 6], "x": 5.5, "y": 1},
+ {"matrix": [1, 7], "x": 6.5, "y": 1},
+ {"matrix": [1, 8], "x": 7.5, "y": 1},
+ {"matrix": [1, 9], "x": 8.5, "y": 1},
+ {"matrix": [1, 10], "x": 9.5, "y": 1},
+ {"matrix": [1, 11], "x": 10.5, "y": 1},
+ {"matrix": [1, 12], "x": 11.5, "y": 1},
+ {"matrix": [1, 13], "x": 12.5, "y": 1},
+ {"matrix": [1, 14], "x": 13.5, "y": 1, "w": 1.5},
+
+ {"matrix": [2, 0], "x": 0, "y": 2, "w": 1.75},
+ {"matrix": [2, 2], "x": 1.75, "y": 2},
+ {"matrix": [2, 3], "x": 2.75, "y": 2},
+ {"matrix": [2, 4], "x": 3.75, "y": 2},
+ {"matrix": [2, 5], "x": 4.75, "y": 2},
+ {"matrix": [2, 6], "x": 5.75, "y": 2},
+ {"matrix": [2, 7], "x": 6.75, "y": 2},
+ {"matrix": [2, 8], "x": 7.75, "y": 2},
+ {"matrix": [2, 9], "x": 8.75, "y": 2},
+ {"matrix": [2, 10], "x": 9.75, "y": 2},
+ {"matrix": [2, 11], "x": 10.75, "y": 2},
+ {"matrix": [2, 12], "x": 11.75, "y": 2},
+ {"matrix": [2, 13], "x": 12.75, "y": 2, "w": 2.25},
+
+ {"matrix": [3, 1], "x": 0, "y": 3, "w": 2.25},
+ {"matrix": [3, 2], "x": 2.25, "y": 3},
+ {"matrix": [3, 3], "x": 3.25, "y": 3},
+ {"matrix": [3, 4], "x": 4.25, "y": 3},
+ {"matrix": [3, 5], "x": 5.25, "y": 3},
+ {"matrix": [3, 6], "x": 6.25, "y": 3},
+ {"matrix": [3, 7], "x": 7.25, "y": 3},
+ {"matrix": [3, 8], "x": 8.25, "y": 3},
+ {"matrix": [3, 9], "x": 9.25, "y": 3},
+ {"matrix": [3, 10], "x": 10.25, "y": 3},
+ {"matrix": [3, 11], "x": 11.25, "y": 3},
+ {"matrix": [3, 13], "x": 12.25, "y": 3, "w": 1.75},
+ {"matrix": [3, 14], "x": 14.0, "y": 3},
+
+ {"matrix": [4, 2], "x": 1.5, "y": 4},
+ {"matrix": [4, 3], "x": 2.5, "y": 4, "w": 1.5},
+ {"matrix": [4, 7], "x": 4, "y": 4, "w": 6},
+ {"matrix": [4, 10], "x": 10, "y": 4, "w": 1.5},
+ {"matrix": [4, 11], "x": 11.5, "y": 4}
+ ]
+ }
+ }
+}
diff --git a/keyboards/void/voidhhkb_hotswap/keymaps/default/keymap.c b/keyboards/void/voidhhkb_hotswap/keymaps/default/keymap.c
new file mode 100644
index 00000000000..3b28a0c1c2e
--- /dev/null
+++ b/keyboards/void/voidhhkb_hotswap/keymaps/default/keymap.c
@@ -0,0 +1,21 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT_60_hhkb(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC,
+ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(1),
+ KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, KC_RALT
+ ),
+ [1] = LAYOUT_60_hhkb(
+ KC_PWR, 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_INS, KC_DEL,
+ KC_CAPS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_PSCR, KC_SCRL, KC_PAUS, KC_UP, KC_NO, KC_CLAG,
+ KC_NO, KC_VOLU, KC_VOLD, KC_MUTE, KC_EJCT, KC_NO, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_RETN,
+ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_NO, KC_TRNS,
+ KC_NO, KC_NO, KC_NO, KC_MSTP, KC_NO
+ )
+};
diff --git a/keyboards/void/voidhhkb_hotswap/readme.md b/keyboards/void/voidhhkb_hotswap/readme.md
new file mode 100644
index 00000000000..a9b78eefe7c
--- /dev/null
+++ b/keyboards/void/voidhhkb_hotswap/readme.md
@@ -0,0 +1,29 @@
+# VoidHHKB-Hotswap
+
+
+
+VoidHHKB-Hotswap 60% PCB designed for the [HSKB project](https://github.com/Dev01-D/HSKB).
+
+* Keyboard Maintainer: [James Wilson](https://github.com/JamesWilson1996)
+* Hardware Supported: STM32F072CBT6
+* Hardware Availability: [HSKB](https://github.com/Dev01-D/HSKB)
+
+# Compiling
+
+Make example for this keyboard (after setting up your build environment):
+
+ make void/voidhhkb_hotswap:default
+
+Flashing example for this keyboard:
+
+ make void/voidhhkb_hotswap:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+# Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
+* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
+* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
diff --git a/keyboards/work_louder/rgb_functions.c b/keyboards/work_louder/rgb_functions.c
index 15d0f432a08..b0d89d8511e 100644
--- a/keyboards/work_louder/rgb_functions.c
+++ b/keyboards/work_louder/rgb_functions.c
@@ -14,10 +14,10 @@
* along with this program. If not, see .
*/
-#include "rgblight.h"
-#include "rgb_matrix.h"
-
#ifdef RGBLIGHT_ENABLE
+
+#include "rgblight.h"
+
#undef WS2812_DI_PIN
#define WS2812_DI_PIN RGBLIGHT_DI_PIN
diff --git a/lib/python/qmk/build_targets.py b/lib/python/qmk/build_targets.py
index e2df0294907..df5a5ffb42d 100644
--- a/lib/python/qmk/build_targets.py
+++ b/lib/python/qmk/build_targets.py
@@ -11,7 +11,7 @@ from qmk.commands import find_make, get_make_parallel_args, parse_configurator_j
from qmk.keyboard import keyboard_folder
from qmk.info import keymap_json
from qmk.keymap import locate_keymap
-from qmk.path import is_under_qmk_firmware, is_under_qmk_userspace
+from qmk.path import is_under_qmk_firmware, is_under_qmk_userspace, unix_style_path
# These must be kept in the order in which they're applied to $(TARGET) in the makefiles in order to ensure consistency.
TARGET_FILENAME_MODIFIERS = ['FORCE_LAYOUT', 'CONVERT_TO']
@@ -204,11 +204,11 @@ class KeyboardKeymapBuildTarget(BuildTarget):
if is_under_qmk_userspace(keymap_location) and not is_under_qmk_firmware(keymap_location):
keymap_directory = keymap_location.parent
compile_args.extend([
- f'MAIN_KEYMAP_PATH_1={keymap_directory}',
- f'MAIN_KEYMAP_PATH_2={keymap_directory}',
- f'MAIN_KEYMAP_PATH_3={keymap_directory}',
- f'MAIN_KEYMAP_PATH_4={keymap_directory}',
- f'MAIN_KEYMAP_PATH_5={keymap_directory}',
+ f'MAIN_KEYMAP_PATH_1={unix_style_path(keymap_directory)}',
+ f'MAIN_KEYMAP_PATH_2={unix_style_path(keymap_directory)}',
+ f'MAIN_KEYMAP_PATH_3={unix_style_path(keymap_directory)}',
+ f'MAIN_KEYMAP_PATH_4={unix_style_path(keymap_directory)}',
+ f'MAIN_KEYMAP_PATH_5={unix_style_path(keymap_directory)}',
])
return compile_args
@@ -267,11 +267,11 @@ class JsonKeymapBuildTarget(BuildTarget):
generated_files_path = intermediate_output / 'src'
keymap_json = generated_files_path / 'keymap.json'
compile_args.extend([
- f'MAIN_KEYMAP_PATH_1={intermediate_output}',
- f'MAIN_KEYMAP_PATH_2={intermediate_output}',
- f'MAIN_KEYMAP_PATH_3={intermediate_output}',
- f'MAIN_KEYMAP_PATH_4={intermediate_output}',
- f'MAIN_KEYMAP_PATH_5={intermediate_output}',
+ f'MAIN_KEYMAP_PATH_1={unix_style_path(intermediate_output)}',
+ f'MAIN_KEYMAP_PATH_2={unix_style_path(intermediate_output)}',
+ f'MAIN_KEYMAP_PATH_3={unix_style_path(intermediate_output)}',
+ f'MAIN_KEYMAP_PATH_4={unix_style_path(intermediate_output)}',
+ f'MAIN_KEYMAP_PATH_5={unix_style_path(intermediate_output)}',
f'KEYMAP_JSON={keymap_json}',
f'KEYMAP_PATH={generated_files_path}',
])
diff --git a/lib/python/qmk/cli/doctor/check.py b/lib/python/qmk/cli/doctor/check.py
index 89a69302440..6ce6b1d8efd 100644
--- a/lib/python/qmk/cli/doctor/check.py
+++ b/lib/python/qmk/cli/doctor/check.py
@@ -90,10 +90,13 @@ def _check_arm_gcc_installation():
"""Returns OK if the arm-none-eabi-gcc is fully installed and can produce binaries.
"""
with TemporaryDirectory() as temp_dir:
- temp_file = Path(temp_dir) / 'test.elf'
+ temp_in = Path(temp_dir) / 'test.c'
+ temp_out = Path(temp_dir) / 'test.elf'
- args = ['arm-none-eabi-gcc', '-mcpu=cortex-m0', '-mthumb', '-mno-thumb-interwork', '--specs=nosys.specs', '--specs=nano.specs', '-x', 'c', '-o', str(temp_file), '-']
- result = cli.run(args, stdin=None, stdout=None, stderr=None, input='#include \nint main() { return __NEWLIB__ * __NEWLIB_MINOR__ * __NEWLIB_PATCHLEVEL__; }')
+ temp_in.write_text('#include \nint main() { return __NEWLIB__ * __NEWLIB_MINOR__ * __NEWLIB_PATCHLEVEL__; }', encoding='utf-8')
+
+ args = ['arm-none-eabi-gcc', '-mcpu=cortex-m0', '-mthumb', '-mno-thumb-interwork', '--specs=nosys.specs', '--specs=nano.specs', '-x', 'c', '-o', str(temp_out), str(temp_in)]
+ result = cli.run(args, stdout=None, stderr=None)
if result.returncode == 0:
cli.log.info('Successfully compiled using arm-none-eabi-gcc')
else:
@@ -101,8 +104,8 @@ def _check_arm_gcc_installation():
cli.log.error(f'Command: {" ".join(args)}')
return CheckStatus.ERROR
- args = ['arm-none-eabi-size', str(temp_file)]
- result = cli.run(args, stdin=None, stdout=None, stderr=None)
+ args = ['arm-none-eabi-size', str(temp_out)]
+ result = cli.run(args, stdout=None, stderr=None)
if result.returncode == 0:
cli.log.info('Successfully tested arm-none-eabi-binutils using arm-none-eabi-size')
else:
@@ -127,10 +130,13 @@ def _check_avr_gcc_installation():
"""Returns OK if the avr-gcc is fully installed and can produce binaries.
"""
with TemporaryDirectory() as temp_dir:
- temp_file = Path(temp_dir) / 'test.elf'
+ temp_in = Path(temp_dir) / 'test.c'
+ temp_out = Path(temp_dir) / 'test.elf'
- args = ['avr-gcc', '-mmcu=atmega32u4', '-x', 'c', '-o', str(temp_file), '-']
- result = cli.run(args, stdin=None, stdout=None, stderr=None, input='int main() { return 0; }')
+ temp_in.write_text('int main() { return 0; }', encoding='utf-8')
+
+ args = ['avr-gcc', '-mmcu=atmega32u4', '-x', 'c', '-o', str(temp_out), str(temp_in)]
+ result = cli.run(args, stdout=None, stderr=None)
if result.returncode == 0:
cli.log.info('Successfully compiled using avr-gcc')
else:
@@ -138,8 +144,8 @@ def _check_avr_gcc_installation():
cli.log.error(f'Command: {" ".join(args)}')
return CheckStatus.ERROR
- args = ['avr-size', str(temp_file)]
- result = cli.run(args, stdin=None, stdout=None, stderr=None)
+ args = ['avr-size', str(temp_out)]
+ result = cli.run(args, stdout=None, stderr=None)
if result.returncode == 0:
cli.log.info('Successfully tested avr-binutils using avr-size')
else:
diff --git a/lib/python/qmk/cli/generate/make_dependencies.py b/lib/python/qmk/cli/generate/make_dependencies.py
index 331132a20f5..95481878889 100755
--- a/lib/python/qmk/cli/generate/make_dependencies.py
+++ b/lib/python/qmk/cli/generate/make_dependencies.py
@@ -8,7 +8,7 @@ from argcomplete.completers import FilesCompleter
from qmk.commands import dump_lines
from qmk.keyboard import keyboard_completer, keyboard_folder
from qmk.keymap import keymap_completer, locate_keymap
-from qmk.path import normpath, FileType
+from qmk.path import normpath, FileType, unix_style_path
@cli.argument('filename', nargs='?', arg_only=True, type=FileType('r'), completer=FilesCompleter('.json'), help='A configurator export JSON.')
@@ -53,4 +53,4 @@ def generate_make_dependencies(cli):
for file in interesting_files:
check_files.append(Path('users') / cli.args.keymap / file)
- dump_lines(cli.args.output, [f'generated-files: $(wildcard {found})\n' for found in check_files])
+ dump_lines(cli.args.output, [f'generated-files: $(wildcard {unix_style_path(found)})\n' for found in check_files])
diff --git a/lib/python/qmk/cli/lint.py b/lib/python/qmk/cli/lint.py
index c09e377ad67..bcf905f579d 100644
--- a/lib/python/qmk/cli/lint.py
+++ b/lib/python/qmk/cli/lint.py
@@ -317,10 +317,10 @@ def lint(cli):
if isinstance(cli.config.lint.keyboard, str):
# if provided via config - string not array
keyboard_list = [cli.config.lint.keyboard]
- elif is_all_keyboards(cli.args.keyboard[0]):
+ elif any(is_all_keyboards(kb) for kb in cli.args.keyboard):
keyboard_list = list_keyboards()
else:
- keyboard_list = cli.config.lint.keyboard
+ keyboard_list = list(set(cli.config.lint.keyboard))
failed = []
diff --git a/lib/python/qmk/commands.py b/lib/python/qmk/commands.py
index 0e1876ca7ae..ac1455967d7 100644
--- a/lib/python/qmk/commands.py
+++ b/lib/python/qmk/commands.py
@@ -12,6 +12,7 @@ from qmk.constants import QMK_USERSPACE, HAS_QMK_USERSPACE
from qmk.json_schema import json_load, validate
from qmk.keyboard import keyboard_alias_definitions
from qmk.util import maybe_exit
+from qmk.path import unix_style_path
def find_make():
@@ -85,7 +86,7 @@ def build_environment(args):
envs = parse_env_vars(args)
if HAS_QMK_USERSPACE:
- envs['QMK_USERSPACE'] = Path(QMK_USERSPACE).resolve()
+ envs['QMK_USERSPACE'] = unix_style_path(Path(QMK_USERSPACE).resolve())
return envs
diff --git a/platforms/chibios/converters/promicro_to_promicro_rp2040/pre_converter.mk b/platforms/chibios/converters/promicro_to_promicro_rp2040/pre_converter.mk
index 303d3135cef..80111d0f781 100644
--- a/platforms/chibios/converters/promicro_to_promicro_rp2040/pre_converter.mk
+++ b/platforms/chibios/converters/promicro_to_promicro_rp2040/pre_converter.mk
@@ -1,2 +1,8 @@
CONVERTER:=platforms/chibios/converters/promicro_to_sparkfun_pm2040
ACTIVE_CONVERTER:=sparkfun_pm2040
+
+$(info @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@)
+$(info The 'CONVERT_TO=promicro_rp2040' option is now deprecated.)
+$(info Depending on hardware either 'CONVERT_TO=sparkfun_pm2040' or 'CONVERT_TO=rp2040_ce' should be used instead.)
+$(info See https://docs.qmk.fm/feature_converters#pro-micro documentation for more information.)
+$(info @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@)