diff --git a/keyboards/ibm/model_m/config.h b/keyboards/ibm/model_m/config.h
new file mode 100644
index 000000000000..d734af373381
--- /dev/null
+++ b/keyboards/ibm/model_m/config.h
@@ -0,0 +1,44 @@
+/*
+Copyright 2024 Richard George
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+/*
+ * Arduino Pro Micro Pin Mapping
+ * ---------------------------
+ * Physical pin locations preserved from original design:
+ * D5 (Arduino Pin 5) -> PC6 -> QMK: C6 (CS1 - Expander A, address 0x01, long 16-pin connector, columns)
+ * D6 (Arduino Pin 6) -> PD7 -> QMK: D7 (CS2 - Expander B, address 0x00, short 8-pin connector, rows)
+ * D14 (Arduino Pin 14) -> PB3 -> QMK: B3 (MISO)
+ * D15 (Arduino Pin 15) -> PB1 -> QMK: B1 (SCK)
+ * D16 (Arduino Pin 16) -> PB2 -> QMK: B2 (MOSI)
+ *
+ * MCP23S17 Configuration:
+ * - Expander A (CS1): Connected to long 16-pin connector, handles columns, address 0x01
+ * GPA0->pin1, GPA1->pin2, ..., GPA7->pin8, GPB0->pin9, ..., GPB7->pin16
+ * - Expander B (CS2): Connected to short 8-pin connector, handles rows, address 0x00
+ * GPA0->pin1, GPA1->pin2, ..., GPA7->pin8
+ */
+
+/* key matrix size */
+#define MATRIX_ROWS 8
+#define MATRIX_COLS 16
+
+/* SPI for MCP23S17 - mapped to Arduino Pro Micro physical pins */
+#define SPI_DRIVER SPID1 /* Using hardware SPI on pins D14-D16 */
+#define MCP23S17_CS1_PIN C6 /* D5 -> PC6 (CS1 - Expander A for columns) */
+#define MCP23S17_CS2_PIN D7 /* D6 -> PD7 (CS2 - Expander B for rows) */
diff --git a/keyboards/ibm/model_m/keyboard.json b/keyboards/ibm/model_m/keyboard.json
new file mode 100644
index 000000000000..a6f7d559d604
--- /dev/null
+++ b/keyboards/ibm/model_m/keyboard.json
@@ -0,0 +1,143 @@
+{
+ "manufacturer": "rgeorge",
+ "keyboard_name": "model_m",
+ "maintainer": "rgeorge",
+ "bootmagic": {
+ "matrix": [0, 5]
+ },
+ "development_board": "promicro",
+ "features": {
+ "bootmagic": true,
+ "command": true,
+ "extrakey": true,
+ "mousekey": true
+ },
+ "indicators": {
+ "caps_lock": "E6",
+ "num_lock": "B5",
+ "on_state": 0,
+ "scroll_lock": "B4"
+ },
+ "matrix_pins": {
+ "ghost": true
+ },
+ "qmk": {
+ "locking": {
+ "enabled": true,
+ "resync": true
+ }
+ },
+ "usb": {
+ "device_version": "0.0.1",
+ "pid": "0x0001",
+ "vid": "0x5247"
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"label": "Esc", "matrix": [0, 5], "x": 0, "y": 0},
+ {"label": "F1", "matrix": [2, 4], "x": 2, "y": 0},
+ {"label": "F2", "matrix": [2, 3], "x": 3, "y": 0},
+ {"label": "F3", "matrix": [1, 3], "x": 4, "y": 0},
+ {"label": "F4", "matrix": [0, 3], "x": 5, "y": 0},
+ {"label": "F5", "matrix": [0, 1], "x": 6.5, "y": 0},
+ {"label": "F6", "matrix": [0, 8], "x": 7.5, "y": 0},
+ {"label": "F7", "matrix": [1, 9], "x": 8.5, "y": 0},
+ {"label": "F8", "matrix": [2, 9], "x": 9.5, "y": 0},
+ {"label": "F9", "matrix": [2, 1], "x": 11, "y": 0},
+ {"label": "F10", "matrix": [3, 1], "x": 12, "y": 0},
+ {"label": "F11", "matrix": [3, 11], "x": 13, "y": 0},
+ {"label": "F12", "matrix": [3, 12], "x": 14, "y": 0},
+ {"label": "Print Screen", "matrix": [3, 15], "x": 15.5, "y": 0},
+ {"label": "Scroll Lock", "matrix": [4, 15], "x": 16.5, "y": 0},
+ {"label": "Pause", "matrix": [6, 14], "x": 17.5, "y": 0},
+ {"label": "`", "matrix": [2, 5], "x": 0, "y": 1.5},
+ {"label": "1", "matrix": [3, 5], "x": 1, "y": 1.5},
+ {"label": "2", "matrix": [3, 4], "x": 2, "y": 1.5},
+ {"label": "3", "matrix": [3, 3], "x": 3, "y": 1.5},
+ {"label": "4", "matrix": [3, 2], "x": 4, "y": 1.5},
+ {"label": "5", "matrix": [2, 2], "x": 5, "y": 1.5},
+ {"label": "6", "matrix": [2, 0], "x": 6, "y": 1.5},
+ {"label": "7", "matrix": [3, 0], "x": 7, "y": 1.5},
+ {"label": "8", "matrix": [3, 8], "x": 8, "y": 1.5},
+ {"label": "9", "matrix": [3, 9], "x": 9, "y": 1.5},
+ {"label": "0", "matrix": [3, 10], "x": 10, "y": 1.5},
+ {"label": "-", "matrix": [2, 10], "x": 11, "y": 1.5},
+ {"label": "=", "matrix": [2, 8], "x": 12, "y": 1.5},
+ {"label": "Backspace", "matrix": [1, 1], "x": 14, "y": 1.5, "w": 2},
+ {"label": "Insert", "matrix": [2, 12], "x": 15.5, "y": 1.5},
+ {"label": "Home", "matrix": [2, 14], "x": 16.5, "y": 1.5},
+ {"label": "Page Up", "matrix": [2, 13], "x": 17.5, "y": 1.5},
+ {"label": "Num Lock", "matrix": [6, 11], "x": 19, "y": 1.5},
+ {"label": "/", "matrix": [6, 12], "x": 20, "y": 1.5},
+ {"label": "*", "matrix": [6, 13], "x": 21, "y": 1.5},
+ {"label": "-", "matrix": [7, 13], "x": 22, "y": 1.5},
+ {"label": "Tab", "matrix": [1, 5], "x": 0, "y": 2.5, "w": 1.5},
+ {"label": "Q", "matrix": [4, 5], "x": 1.5, "y": 2.5},
+ {"label": "W", "matrix": [4, 4], "x": 2.5, "y": 2.5},
+ {"label": "E", "matrix": [4, 3], "x": 3.5, "y": 2.5},
+ {"label": "R", "matrix": [4, 2], "x": 4.5, "y": 2.5},
+ {"label": "T", "matrix": [1, 2], "x": 5.5, "y": 2.5},
+ {"label": "Y", "matrix": [1, 0], "x": 6.5, "y": 2.5},
+ {"label": "U", "matrix": [4, 0], "x": 7.5, "y": 2.5},
+ {"label": "I", "matrix": [4, 8], "x": 8.5, "y": 2.5},
+ {"label": "O", "matrix": [4, 9], "x": 9.5, "y": 2.5},
+ {"label": "P", "matrix": [4, 10], "x": 10.5, "y": 2.5},
+ {"label": "[", "matrix": [1, 10], "x": 11.5, "y": 2.5},
+ {"label": "]", "matrix": [1, 8], "x": 12.5, "y": 2.5},
+ {"label": "Enter", "matrix": [6, 1], "x": 13.5, "y": 2.5, "w": 1.5},
+ {"label": "Delete", "matrix": [2, 11], "x": 15.5, "y": 2.5},
+ {"label": "End", "matrix": [3, 14], "x": 16.5, "y": 2.5},
+ {"label": "Page Down", "matrix": [3, 13], "x": 17.5, "y": 2.5},
+ {"label": "7", "matrix": [4, 11], "x": 19, "y": 2.5},
+ {"label": "8", "matrix": [4, 12], "x": 20, "y": 2.5},
+ {"label": "9", "matrix": [4, 13], "x": 21, "y": 2.5},
+ {"label": "+", "matrix": [4, 14], "x": 22, "y": 2.5, "h": 2},
+ {"label": "Caps Lock", "matrix": [1, 4], "x": 0, "y": 3.5, "w": 1.25},
+ {"label": "A", "matrix": [5, 5], "x": 1.75, "y": 3.5},
+ {"label": "S", "matrix": [5, 4], "x": 2.75, "y": 3.5},
+ {"label": "D", "matrix": [5, 3], "x": 3.75, "y": 3.5},
+ {"label": "F", "matrix": [5, 2], "x": 4.75, "y": 3.5},
+ {"label": "G", "matrix": [0, 2], "x": 5.75, "y": 3.5},
+ {"label": "H", "matrix": [0, 0], "x": 6.75, "y": 3.5},
+ {"label": "J", "matrix": [5, 0], "x": 7.75, "y": 3.5},
+ {"label": "K", "matrix": [5, 8], "x": 8.75, "y": 3.5},
+ {"label": "L", "matrix": [5, 9], "x": 9.75, "y": 3.5},
+ {"label": ";", "matrix": [5, 10], "x": 10.75, "y": 3.5},
+ {"label": "'", "matrix": [0, 10], "x": 11.75, "y": 3.5},
+ {"label": "#", "matrix": [5, 1], "x": 12.75, "y": 3.5},
+ {"label": "4", "matrix": [1, 11], "x": 19, "y": 3.5},
+ {"label": "5", "matrix": [1, 12], "x": 20, "y": 3.5},
+ {"label": "6", "matrix": [1, 13], "x": 21, "y": 3.5},
+ {"label": "Shift", "matrix": [1, 6], "x": 0, "y": 4.5, "w": 1.25},
+ {"label": "\\", "matrix": [7, 4], "x": 1.25, "y": 4.5},
+ {"label": "Z", "matrix": [6, 5], "x": 2.25, "y": 4.5},
+ {"label": "X", "matrix": [6, 4], "x": 3.25, "y": 4.5},
+ {"label": "C", "matrix": [6, 3], "x": 4.25, "y": 4.5},
+ {"label": "V", "matrix": [6, 2], "x": 5.25, "y": 4.5},
+ {"label": "B", "matrix": [7, 2], "x": 6.25, "y": 4.5},
+ {"label": "N", "matrix": [7, 0], "x": 7.25, "y": 4.5},
+ {"label": "M", "matrix": [6, 0], "x": 8.25, "y": 4.5},
+ {"label": ",", "matrix": [6, 8], "x": 9.25, "y": 4.5},
+ {"label": ".", "matrix": [6, 9], "x": 10.25, "y": 4.5},
+ {"label": "/", "matrix": [7, 10], "x": 11.25, "y": 4.5},
+ {"label": "Shift", "matrix": [6, 6], "x": 12.25, "y": 4.5, "w": 2.75},
+ {"label": "Up", "matrix": [0, 14], "x": 16.5, "y": 4.5},
+ {"label": "1", "matrix": [5, 11], "x": 19, "y": 4.5},
+ {"label": "2", "matrix": [5, 12], "x": 20, "y": 4.5},
+ {"label": "3", "matrix": [5, 13], "x": 21, "y": 4.5},
+ {"label": "Enter", "matrix": [5, 14], "x": 22, "y": 4.5, "h": 2},
+ {"label": "Ctrl", "matrix": [2, 7], "x": 0, "y": 5.5, "w": 1.5},
+ {"label": "Alt", "matrix": [0, 15], "x": 2.5, "y": 5.5, "w": 1.5},
+ {"label": "Space", "matrix": [7, 1], "x": 4, "y": 5.5, "w": 7},
+ {"label": "AltGr", "matrix": [7, 15], "x": 11, "y": 5.5, "w": 1.5},
+ {"label": "Menu", "matrix": [6, 7], "x": 13.5, "y": 5.5, "w": 1.5},
+ {"label": "Left", "matrix": [7, 14], "x": 15.5, "y": 5.5},
+ {"label": "Down", "matrix": [7, 11], "x": 16.5, "y": 5.5},
+ {"label": "Right", "matrix": [7, 12], "x": 17.5, "y": 5.5},
+ {"label": "0", "matrix": [0, 12], "x": 19, "y": 5.5, "w": 2},
+ {"label": ".", "matrix": [0, 13], "x": 21, "y": 5.5}
+ ]
+ }
+ }
+}
diff --git a/keyboards/ibm/model_m/matrix.c b/keyboards/ibm/model_m/matrix.c
new file mode 100644
index 000000000000..89b608ca20b1
--- /dev/null
+++ b/keyboards/ibm/model_m/matrix.c
@@ -0,0 +1,214 @@
+/* Copyright 2024 Richard George
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "matrix.h"
+#include "quantum.h"
+#include "spi_master.h"
+#include "gpio.h"
+
+// MCP23S17 register addresses
+#define MCP23S17_IODIRA 0x00 // I/O Direction Register A
+#define MCP23S17_IODIRB 0x01 // I/O Direction Register B
+#define MCP23S17_GPPUA 0x0C // Pull-Up Resistor Configuration Register A
+#define MCP23S17_GPIOA 0x12 // General Purpose I/O Port A
+#define MCP23S17_GPIOB 0x13 // General Purpose I/O Port B
+#define MCP23S17_OLATA 0x14 // Output Latch A
+#define MCP23S17_OLATB 0x15 // Output Latch B
+#define MCP23S17_IOCON 0x0A // I/O Configuration Register (BANK=0 default)
+#define MCP23S17_IOCON_HAEN (1 << 3) // Hardware Address Enable (bit 3 of IOCON)
+
+// MCP23S17 command byte (device address + read/write bit)
+#define MCP23S17_CMD_WRITE(addr) (0x40 | ((addr) << 1))
+#define MCP23S17_CMD_READ(addr) (0x41 | ((addr) << 1))
+
+// MCP23S17 chip select pins (for two expanders)
+#define MCP23S17_CS1 (uint8_t) MCP23S17_CS1_PIN // CS for expander A (columns), address 0x01
+#define MCP23S17_CS2 (uint8_t) MCP23S17_CS2_PIN // CS for expander B (rows), address 0x00
+
+// MCP23S17 register read/write functions
+static void mcp23s17_init_expander(uint8_t cs_pin, uint8_t addr, uint8_t iodir_a, uint8_t iodir_b);
+static void mcp23s17_write_reg(uint8_t cs_pin, uint8_t addr, uint8_t reg_addr, uint8_t data);
+static uint8_t mcp23s17_read_reg(uint8_t cs_pin, uint8_t addr, uint8_t reg_addr);
+
+// Matrix scanning via MCP23S17 port expanders
+static void select_col(uint8_t col);
+static void unselect_cols(void);
+static matrix_row_t read_rows(void);
+
+void keyboard_pre_init_kb(void) {
+ // Initialize SPI master
+ spi_init();
+
+ // Set chip select pins as output
+ gpio_set_pin_output(MCP23S17_CS1);
+ gpio_set_pin_output(MCP23S17_CS2);
+
+ // Deselect both chips (active low, so write HIGH)
+ gpio_write_pin_high(MCP23S17_CS1);
+ gpio_write_pin_high(MCP23S17_CS2);
+
+ keyboard_pre_init_user();
+}
+
+//------------------------------------------------------------------------------
+// Custom Matrix Implementation
+//------------------------------------------------------------------------------
+
+void matrix_init_custom(void) {
+ // Initialize MCP23S17 expanders here so they're ready before bootmagic runs.
+
+ // Enable HAEN (Hardware Address Enable) on both expanders so they only
+ // respond to their assigned address (bit 3 of IOCON, register 0x0A).
+ // Use address 0x00 for the initial write (before HAEN is enabled).
+ mcp23s17_write_reg(MCP23S17_CS2, 0x00, MCP23S17_IOCON, MCP23S17_IOCON_HAEN);
+ mcp23s17_write_reg(MCP23S17_CS1, 0x00, MCP23S17_IOCON, MCP23S17_IOCON_HAEN);
+
+ // Expander B (CS2, addr 0x00) - Short 8-pin connector (Rows), all inputs
+ mcp23s17_init_expander(MCP23S17_CS2, 0x00, 0xFF, 0xFF);
+ // Enable pull-ups on row expander GPA0-GPA7
+ mcp23s17_write_reg(MCP23S17_CS2, 0x00, MCP23S17_GPPUA, 0xFF);
+
+ // Expander A (CS1, addr 0x01) - Long 16-pin connector (Columns)
+ // First init as all outputs with OLAT=0xFF (HIGH) so the output latches are set,
+ // then switch to all inputs (high-impedance) for diodeless-safe scanning.
+ mcp23s17_init_expander(MCP23S17_CS1, 0x01, 0x00, 0x00);
+ mcp23s17_write_reg(MCP23S17_CS1, 0x01, MCP23S17_IODIRA, 0xFF);
+ mcp23s17_write_reg(MCP23S17_CS1, 0x01, MCP23S17_IODIRB, 0xFF);
+}
+
+bool matrix_scan_custom(matrix_row_t current_matrix[]) {
+ bool changed = false;
+
+ unselect_cols();
+ for (uint8_t col = 0; col < MATRIX_COLS; col++) {
+ select_col(col);
+ wait_us(30); // Let signals settle
+
+ matrix_row_t rows = read_rows();
+
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ bool prev_bit = (current_matrix[row] >> col) & 1;
+ bool curr_bit = !((rows >> row) & 1);
+
+ if (prev_bit != curr_bit) {
+ changed = true;
+ }
+
+ if (curr_bit) {
+ current_matrix[row] |= (1 << col);
+ } else {
+ current_matrix[row] &= ~(1 << col);
+ }
+ }
+ }
+ unselect_cols();
+
+ return changed;
+}
+
+//------------------------------------------------------------------------------
+// MCP23S17 Hardware Interface
+//------------------------------------------------------------------------------
+
+static void mcp23s17_init_expander(uint8_t cs_pin, uint8_t addr, uint8_t iodir_a, uint8_t iodir_b) {
+ // Set I/O direction registers
+ mcp23s17_write_reg(cs_pin, addr, MCP23S17_IODIRA, iodir_a);
+ mcp23s17_write_reg(cs_pin, addr, MCP23S17_IODIRB, iodir_b);
+
+ // Set output latches HIGH (inactive) so columns default to non-driven state
+ if (iodir_a == 0x00) {
+ mcp23s17_write_reg(cs_pin, addr, MCP23S17_OLATA, 0xFF);
+ }
+ if (iodir_b == 0x00) {
+ mcp23s17_write_reg(cs_pin, addr, MCP23S17_OLATB, 0xFF);
+ }
+}
+
+static void mcp23s17_write_reg(uint8_t cs_pin, uint8_t addr, uint8_t reg_addr, uint8_t data) {
+ // Start SPI transaction: MSB first, mode 0, divisor 16 (1MHz on 16MHz Pro Micro)
+ if (spi_start(cs_pin, false, 0, 16)) {
+ // Send command byte (device address + write bit)
+ spi_write(MCP23S17_CMD_WRITE(addr));
+ // Send register address
+ spi_write(reg_addr);
+ // Send data
+ spi_write(data);
+ // End SPI transaction
+ spi_stop();
+ }
+}
+
+static uint8_t mcp23s17_read_reg(uint8_t cs_pin, uint8_t addr, uint8_t reg_addr) {
+ uint8_t data = 0;
+
+ // Start SPI transaction: MSB first, mode 0, divisor 16 (1MHz on 16MHz Pro Micro)
+ if (spi_start(cs_pin, false, 0, 16)) {
+ // Send command byte (device address + read bit)
+ spi_write(MCP23S17_CMD_READ(addr));
+ // Send register address
+ spi_write(reg_addr);
+ // Read data
+ data = spi_read();
+ // End SPI transaction
+ spi_stop();
+ }
+
+ return data;
+}
+
+//------------------------------------------------------------------------------
+// Matrix Scanning: Column Selection + Row Reading via Port Expanders
+//------------------------------------------------------------------------------
+
+static void select_col(uint8_t col) {
+ // Expander A (addr 0x01, columns)
+ // For a diodeless matrix, inactive columns must be high-impedance (input mode),
+ // NOT driven HIGH. Driving inactive columns HIGH creates sneak paths when two
+ // pressed keys share a row (current path: inactive HIGH -> switch -> row -> switch -> active LOW).
+ //
+ // Sequence:
+ // 1. Set ALL columns to input (high-Z) — ensures no old column is still driven
+ // 2. Write the output latch (GPIO) with the new column's value (LOW)
+ // 3. Set only the active column as output — pin drives the latch value immediately
+ //
+ // This avoids the glitch where GPIO changes while the old column is still an output,
+ // which would briefly drive it HIGH and create a sneak path.
+
+ mcp23s17_write_reg(MCP23S17_CS1, 0x01, MCP23S17_IODIRA, 0xFF);
+ mcp23s17_write_reg(MCP23S17_CS1, 0x01, MCP23S17_IODIRB, 0xFF);
+
+ if (col < 8) {
+ mcp23s17_write_reg(MCP23S17_CS1, 0x01, MCP23S17_GPIOA, ~(1 << col));
+ mcp23s17_write_reg(MCP23S17_CS1, 0x01, MCP23S17_IODIRA, ~(1 << col));
+ } else {
+ mcp23s17_write_reg(MCP23S17_CS1, 0x01, MCP23S17_GPIOB, ~(1 << (col - 8)));
+ mcp23s17_write_reg(MCP23S17_CS1, 0x01, MCP23S17_IODIRB, ~(1 << (col - 8)));
+ }
+ wait_us(1);
+}
+
+static void unselect_cols(void) {
+ // Set all columns to input (high-impedance) to avoid contention
+ mcp23s17_write_reg(MCP23S17_CS1, 0x01, MCP23S17_IODIRA, 0xFF);
+ mcp23s17_write_reg(MCP23S17_CS1, 0x01, MCP23S17_IODIRB, 0xFF);
+}
+
+static matrix_row_t read_rows(void) {
+ // Expander B (addr 0x00, rows)
+ // Read GPA0-GPA7 from row expander
+ uint8_t row_data = mcp23s17_read_reg(MCP23S17_CS2, 0x00, MCP23S17_GPIOA);
+ return row_data;
+}
diff --git a/keyboards/ibm/model_m/readme.md b/keyboards/ibm/model_m/readme.md
new file mode 100644
index 000000000000..172c17ba2745
--- /dev/null
+++ b/keyboards/ibm/model_m/readme.md
@@ -0,0 +1,21 @@
+# Model M
+
+A custom IBM Model M compatible keyboard controller using QMK firmware. Uses two MCP23S17 SPI port expanders to scan the 8x16 key matrix, with standard Model M connector pinout compatibility.
+
+* Keyboard Maintainer: [Richard George](https://github.com/rgeorge1926-oss)
+* Hardware Supported: Model-C PCB with ATmega32U4 (Arduino Pro Micro) and two MCP23S17 port expanders
+
+Make example for this keyboard (after setting up your build environment):
+
+ qmk compile -kb ibm/model_m -km default
+
+Flashing example for this keyboard:
+
+ qmk flash -kb ibm/model_m -km default
+
+## Bootloader
+
+* **Bootloader reset**: Hold the key at matrix position (0,5) (Esc) and plug in the keyboard
+* **Physical reset**: Briefly short the RST pin on the Pro Micro to GND
+
+See the [build environment setup](https://docs.qmk.fm/#/newbs_getting_started) and the [make instructions](https://docs.qmk.fm/#/faq_build) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/ibm/model_m/rgeorge/README.md b/keyboards/ibm/model_m/rgeorge/README.md
new file mode 100644
index 000000000000..25f2a9fdab28
--- /dev/null
+++ b/keyboards/ibm/model_m/rgeorge/README.md
@@ -0,0 +1,4 @@
+# Model M - rgeorge
+
+The corresponding PCB hardware can be found at:
+https://gitlab.com/richard.george/model-c
diff --git a/keyboards/ibm/model_m/rgeorge/capslayer/config.h b/keyboards/ibm/model_m/rgeorge/capslayer/config.h
new file mode 100644
index 000000000000..08b49c0ebbae
--- /dev/null
+++ b/keyboards/ibm/model_m/rgeorge/capslayer/config.h
@@ -0,0 +1,6 @@
+// Copyright 2024 Richard George
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+#define UNICODE_SELECTED_MODES UNICODE_MODE_LINUX
+#define UNICODE_TYPE_DELAY 100
diff --git a/keyboards/ibm/model_m/rgeorge/capslayer/ideal_mapping.txt b/keyboards/ibm/model_m/rgeorge/capslayer/ideal_mapping.txt
new file mode 100644
index 000000000000..367e4c137e44
--- /dev/null
+++ b/keyboards/ibm/model_m/rgeorge/capslayer/ideal_mapping.txt
@@ -0,0 +1,151 @@
+#include "kb.h"
+
+enum unicode_names {
+ DE_ESZ,
+ DE_EUR,
+ DE_UE_HIGH,
+ DE_AE_HIGH,
+ DE_OE_HIGH,
+ DE_UE_LOW,
+ DE_AE_LOW,
+ DE_OE_LOW,
+};
+
+
+
+const uint32_t PROGMEM unicode_map[] = {
+ [DE_ESZ] = 0x00DF,
+ [DE_EUR] = L'€',
+ [DE_UE_HIGH]= 0x00DC,
+ [DE_AE_HIGH]= 0x00C4,
+ [DE_OE_HIGH]= 0x00D6,
+ [DE_UE_LOW] = 0x00FC ,
+ [DE_AE_LOW] = 0x00E4,
+ [DE_OE_LOW] = 0x00F6,
+};
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ KEYMAP(
+ 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_NO, KC_BSPC,
+ 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_ENT, KC_GRV,
+ MO(1), 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_NO,
+ 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_NO, KC_UP, KC_NO,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_NO, KC_LEFT, KC_DOWN, KC_RGHT, KC_DEL),
+
+ KEYMAP(
+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_BSPC, KC_TRNS,
+KC_TAB, KC_Q, KC_W, X(DE_EUR), KC_R, KC_T, KC_Y, XP(DE_UE_LOW, DE_UE_HIGH), KC_I, XP(DE_OE_LOW, DE_OE_HIGH), KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_VOLD,
+MO(1), XP(DE_AE_LOW,DE_AE_HIGH), X(DE_ESZ), KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_NO,
+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_HOME, KC_PGDN, KC_END, KC_VOLU),
+
+
+
+
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ KEYMAP(
+ 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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
+
+};
+
+
+void matrix_init_user(void) {
+ set_unicode_input_mode(UC_LNX); // or UC_WINC
+};
diff --git a/keyboards/ibm/model_m/rgeorge/capslayer/keymap.c b/keyboards/ibm/model_m/rgeorge/capslayer/keymap.c
new file mode 100644
index 000000000000..1ecfc9341493
--- /dev/null
+++ b/keyboards/ibm/model_m/rgeorge/capslayer/keymap.c
@@ -0,0 +1,67 @@
+// Copyright 2024 Richard George
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+enum unicode_names {
+ UE_LOW, // ü
+ UE_HIGH, // Ü
+ AE_LOW, // ä
+ AE_HIGH, // Ä
+ OE_LOW, // ö
+ OE_HIGH, // Ö
+ SZ_LOW, // ß
+ SZ_HIGH, // ẞ
+ EURO, // €
+};
+
+const uint32_t PROGMEM unicode_map[] = {
+ [UE_LOW] = 0x00FC, // ü
+ [UE_HIGH] = 0x00DC, // Ü
+ [AE_LOW] = 0x00E4, // ä
+ [AE_HIGH] = 0x00C4, // Ä
+ [OE_LOW] = 0x00F6, // ö
+ [OE_HIGH] = 0x00D6, // Ö
+ [SZ_LOW] = 0x00DF, // ß
+ [SZ_HIGH] = 0x1E9E, // ẞ
+ [EURO] = 0x20AC, // €
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [0] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SCRL, KC_PAUS,
+
+ 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_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP,
+ KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
+
+ 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_DEL, KC_END, KC_PGDN,
+ KC_P7, KC_P8, KC_P9, KC_PPLS,
+
+ MO(1), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_P4, KC_P5, KC_P6,
+
+ 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_UP, KC_P1, KC_P2, KC_P3, KC_PENT,
+
+ KC_LCTL, KC_LALT, KC_SPC, KC_RALT, KC_LGUI, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT
+ ),
+
+ [1] = 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, 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_VOLU,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS, KC_TRNS, KC_TRNS, UM(EURO), KC_TRNS, KC_TRNS, KC_TRNS, UP(UE_LOW, UE_HIGH), KC_TRNS, UP(OE_LOW, OE_HIGH), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLD,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+
+ KC_TRNS, UP(AE_LOW, AE_HIGH), UP(SZ_LOW, SZ_HIGH), 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_HOME, KC_PGDN, KC_END, KC_TRNS, KC_TRNS
+ )
+};
+
+void matrix_init_user(void) {
+ set_unicode_input_mode(UNICODE_MODE_LINUX);
+}
diff --git a/keyboards/ibm/model_m/rgeorge/capslayer/readme.md b/keyboards/ibm/model_m/rgeorge/capslayer/readme.md
new file mode 100644
index 000000000000..3ee9ee09ed56
--- /dev/null
+++ b/keyboards/ibm/model_m/rgeorge/capslayer/readme.md
@@ -0,0 +1,3 @@
+# Model-C Default Keymap
+
+This is the default keymap for the Model-C keyboard.
diff --git a/keyboards/ibm/model_m/rgeorge/capslayer/rules.mk b/keyboards/ibm/model_m/rgeorge/capslayer/rules.mk
new file mode 100644
index 000000000000..502b2def7623
--- /dev/null
+++ b/keyboards/ibm/model_m/rgeorge/capslayer/rules.mk
@@ -0,0 +1 @@
+UNICODEMAP_ENABLE = yes
diff --git a/keyboards/ibm/model_m/rgeorge/default/keymap.c b/keyboards/ibm/model_m/rgeorge/default/keymap.c
new file mode 100644
index 000000000000..413677b91b99
--- /dev/null
+++ b/keyboards/ibm/model_m/rgeorge/default/keymap.c
@@ -0,0 +1,23 @@
+// Copyright 2024 Richard George
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [0] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SCRL, KC_PAUS,
+
+ 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_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP,
+ KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
+
+ 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_DEL, KC_END, KC_PGDN,
+ KC_P7, KC_P8, KC_P9, KC_PPLS,
+
+ 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_NUHS, KC_P4, KC_P5, KC_P6,
+
+ 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_UP, KC_P1, KC_P2, KC_P3, KC_PENT,
+
+ KC_LCTL, KC_LALT, KC_SPC, KC_RALT, KC_LGUI, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT
+ )
+};
diff --git a/keyboards/ibm/model_m/rgeorge/default/readme.md b/keyboards/ibm/model_m/rgeorge/default/readme.md
new file mode 100644
index 000000000000..d55895dd11ce
--- /dev/null
+++ b/keyboards/ibm/model_m/rgeorge/default/readme.md
@@ -0,0 +1,3 @@
+# Model M Default Keymap
+
+This is the default keymap for the Model M keyboard.
diff --git a/keyboards/ibm/model_m/rgeorge/default/rules.mk b/keyboards/ibm/model_m/rgeorge/default/rules.mk
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/keyboards/ibm/model_m/rules.mk b/keyboards/ibm/model_m/rules.mk
new file mode 100644
index 000000000000..410345593565
--- /dev/null
+++ b/keyboards/ibm/model_m/rules.mk
@@ -0,0 +1,5 @@
+SPI_DRIVER_REQUIRED = yes
+
+CUSTOM_MATRIX = lite
+
+SRC += matrix.c