From 5ffd95694fafa4fb424c9f0122d6f07a486cd81f Mon Sep 17 00:00:00 2001
From: Pete Johanson <peter@peterjohanson.com>
Date: Sat, 27 Jun 2020 00:16:15 -0400
Subject: [PATCH] Kyria left/right overlays, matrix transform fixes

* Refactor Kyria into separate left/right "revisions"
  of the Kyria shield, and include central
  kyria.dtsi file with common definition.
* Fixes for keymaps to work fully with matrix
  transforms that override effective rows/columns.
* Add ability for matrix transform to do row/col
  offsets, which is needed for split keyboards.
---
 .github/workflows/build.yml                   |  2 +-
 app/boards/shields/kyria/Kconfig.defconfig    |  2 +-
 app/boards/shields/kyria/Kconfig.shield       |  7 +-
 .../shields/kyria/keymap/keymap.overlay       |  2 +-
 .../kyria/{kyria.overlay => kyria.dtsi}       | 65 ++-----------------
 app/boards/shields/kyria/kyria_left.overlay   | 21 ++++++
 app/boards/shields/kyria/kyria_right.overlay  | 25 +++++++
 app/dts/bindings/zmk,matrix-transform.yaml    |  9 +++
 app/include/zmk/matrix.h                      | 13 ++++
 app/src/keymap.c                              |  2 +-
 app/src/matrix_transform.c                    | 22 ++++---
 11 files changed, 98 insertions(+), 72 deletions(-)
 rename app/boards/shields/kyria/{kyria.overlay => kyria.dtsi} (60%)
 create mode 100644 app/boards/shields/kyria/kyria_left.overlay
 create mode 100644 app/boards/shields/kyria/kyria_right.overlay

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c823fb46..230e33f6 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -9,7 +9,7 @@ jobs:
     strategy:
       matrix:
         board: [proton_c, nice_nano]
-        shield: [kyria, petejohanson_pro_micro_handwire]
+        shield: [kyria_left, kyria_right, petejohanson_pro_micro_handwire]
     steps:
       # To use this repository's private action,
       # you must check out the repository
diff --git a/app/boards/shields/kyria/Kconfig.defconfig b/app/boards/shields/kyria/Kconfig.defconfig
index 0bd35625..25af5376 100644
--- a/app/boards/shields/kyria/Kconfig.defconfig
+++ b/app/boards/shields/kyria/Kconfig.defconfig
@@ -1,5 +1,5 @@
 
-if SHIELD_KYRIA
+if SHIELD_KYRIA_LEFT || SHIELD_KYRIA_RIGHT
 
 config ZMK_KEYBOARD_NAME
 	default "Kyria"
diff --git a/app/boards/shields/kyria/Kconfig.shield b/app/boards/shields/kyria/Kconfig.shield
index 598fc81e..7dee0449 100644
--- a/app/boards/shields/kyria/Kconfig.shield
+++ b/app/boards/shields/kyria/Kconfig.shield
@@ -1,5 +1,8 @@
 # Copyright (c) 2020 Pete Johanson
 # SPDX-License-Identifier: MIT
 
-config SHIELD_KYRIA
-	def_bool $(shields_list_contains,kyria)
+config SHIELD_KYRIA_LEFT
+	def_bool $(shields_list_contains,kyria_left)
+
+config SHIELD_KYRIA_RIGHT
+	def_bool $(shields_list_contains,kyria_right)
diff --git a/app/boards/shields/kyria/keymap/keymap.overlay b/app/boards/shields/kyria/keymap/keymap.overlay
index f61bb6ce..0c00aef8 100644
--- a/app/boards/shields/kyria/keymap/keymap.overlay
+++ b/app/boards/shields/kyria/keymap/keymap.overlay
@@ -26,7 +26,7 @@
 			bindings = <
 	&kp ESC  &kp Q &kp W &kp E &kp R &kp T                                            &kp Y &kp U  &kp I    &kp O   &kp P    &kp PIPE
 	&kp BKSP &kp A &kp S &kp D &kp F &kp G                                            &kp H &kp J  &kp K    &kp L   &kp SCLN &kp QUOT
-	&kp LSFT &kp Z &kp X &kp C &kp V &kp B &kp  LSFT &kp LSFT       &kp LSFT &kp LSFT &kp N &kp M  &kp CMMA &kp DOT &kp BSLH &kp MINUS
+	&kp LSFT &kp Z &kp X &kp C &kp V &kp B &kp LSFT &kp LSFT       &kp LSFT &kp LSFT &kp N &kp M  &kp CMMA &kp DOT &kp BSLH &kp MINUS
 	                     &kp LGUI &kp DEL &kp RET &kp SPC &kp ESC       &kp RET  &kp SPC  &kp TAB &kp BKSP &kp RALT
 			>;
 		};
diff --git a/app/boards/shields/kyria/kyria.overlay b/app/boards/shields/kyria/kyria.dtsi
similarity index 60%
rename from app/boards/shields/kyria/kyria.overlay
rename to app/boards/shields/kyria/kyria.dtsi
index 85b22bec..f96adf0f 100644
--- a/app/boards/shields/kyria/kyria.overlay
+++ b/app/boards/shields/kyria/kyria.dtsi
@@ -5,36 +5,17 @@
  */
 
 #include <dt-bindings/zmk/matrix-transform.h>
-#include <behaviors/keymap.dtsi>
-#include <behaviors/hid.dtsi>
 
 / {
 	chosen {
-		zmk,kscan = &kscan_left;
+		zmk,kscan = &kscan0;
 		zmk,matrix_transform = &default_transform;
 	};
 
-	kscan0: kscan_comp {
-		compatible = "zmk,kscan-composite";
-
-		label = "KSCAN_COMP";
-		rows = <4>;
-		columns = <16>;
-
-		left {
-			kscan = <&kscan_left>;
-		};
-
-		// right {
-		// 	kscan = <&kscan_right>;
-		// 	 // TODO: Actually put this in the kscan driver, so it can report
-		// 	 // HID events directly to host if plugged in directly.
-		// 	column-offset = <8>;
-		// };
-	};
-
 	default_transform: keymap_transform_0 {
 		compatible = "zmk,matrix-transform";
+		columns = <16>;
+		rows = <4>;
 // | MX6  | MX5  | MX4  | MX3  | MX2  | MX1  |                               | MX1  | MX2  | MX3  | MX4  | MX5  | MX6  |
 // | MX12 | MX11 | MX10 | MX9  | MX8  | MX7  |                               | MX7  | MX8  | MX9  | MX10 | MX11 | MX12 |
 // | MX20 | MX19 | MX18 | MX17 | MX16 | MX15 | MX14 | MX13 |   | MX13 | MX14 | MX15 | MX16 | MX17 | MX18 | MX19 | MX20 |
@@ -53,6 +34,8 @@ RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9)
 //             | MX25 | MX24 | MX23 | MX22 | MX21 |       | MX21 | MX22 | MX23 | MX24 | MX25 |
 	five_column_transform: keymap_transform_1 {
 		compatible = "zmk,matrix-transform";
+		columns = <14>;
+		rows = <4>;
 		map = <
 RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4)                                 RC(0,9) RC(0,10) RC(0,11) RC(0,12) RC(0,13)
 RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4)                                 RC(1,9) RC(1,10) RC(1,11) RC(1,12) RC(1,13)
@@ -61,9 +44,9 @@ RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9)
 		>;
 	};
 
-	kscan_left: kscan_left {
+	kscan0: kscan {
 		compatible = "zmk,kscan-gpio-matrix";
-		label = "KSCAN_LEFT";
+		label = "KSCAN";
 
 		diode-direction = "col2row";
 		row-gpios
@@ -72,43 +55,9 @@ RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9)
 			, <&pro_micro_d 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
 			, <&pro_micro_d 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
 			;
-
-		col-gpios
-			= <&pro_micro_a 3 (GPIO_ACTIVE_HIGH)>
-			, <&pro_micro_a 2 (GPIO_ACTIVE_HIGH)>
-			, <&pro_micro_a 1 (GPIO_ACTIVE_HIGH)>
-			, <&pro_micro_a 0 (GPIO_ACTIVE_HIGH)>
-			, <&pro_micro_d 15 (GPIO_ACTIVE_HIGH)>
-			, <&pro_micro_d 14 (GPIO_ACTIVE_HIGH)>
-			, <&pro_micro_d 16 (GPIO_ACTIVE_HIGH)>
-			, <&pro_micro_d 10 (GPIO_ACTIVE_HIGH)>
-			;
 		
 	};
 
-	// kscan_right: kscan_right {
-	// 	compatible = "zmk,kscan-gpio-matrix";
-	// 	label = "KSCAN_RIGHT";
-
-	// 	diode-direction = "col2row";
-	// 	row-gpios
-	// 		= <&pro_micro_d 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-	// 		, <&pro_micro_d 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-	// 		, <&pro_micro_d 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-	// 		, <&pro_micro_d 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-	// 		;
-		// col-gpios
-		// 	= <&pro_micro_d 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-		// 	, <&pro_micro_d 16 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-		// 	, <&pro_micro_d 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-		// 	, <&pro_micro_d 15 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-		// 	, <&pro_micro_a 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-		// 	, <&pro_micro_a 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-		// 	, <&pro_micro_a 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-		// 	, <&pro_micro_a 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
-		// 	;
-	// };
-
 	// TODO: Encoder node(s)
 	// TODO: OLED node
 	// TODO: RGB node(s)
diff --git a/app/boards/shields/kyria/kyria_left.overlay b/app/boards/shields/kyria/kyria_left.overlay
new file mode 100644
index 00000000..c6305bd8
--- /dev/null
+++ b/app/boards/shields/kyria/kyria_left.overlay
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2020 Pete Johanson
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "kyria.dtsi"
+
+&kscan0 {
+	col-gpios
+		= <&pro_micro_a  3 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_a  2 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_a  1 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_a  0 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_d 15 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_d 14 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_d 16 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_d 10 GPIO_ACTIVE_HIGH>
+		;
+};
+
diff --git a/app/boards/shields/kyria/kyria_right.overlay b/app/boards/shields/kyria/kyria_right.overlay
new file mode 100644
index 00000000..b919bb2a
--- /dev/null
+++ b/app/boards/shields/kyria/kyria_right.overlay
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020 Pete Johanson
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "kyria.dtsi"
+
+&default_transform {
+	col-offset = <8>;
+};
+
+&kscan0 {
+	col-gpios
+		= <&pro_micro_d 10 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_d 16 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_d 14 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_d 15 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_a  0 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_a  1 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_a  2 GPIO_ACTIVE_HIGH>
+		, <&pro_micro_a  3 GPIO_ACTIVE_HIGH>
+		;
+};
+
diff --git a/app/dts/bindings/zmk,matrix-transform.yaml b/app/dts/bindings/zmk,matrix-transform.yaml
index 453da9d7..b7d000c5 100644
--- a/app/dts/bindings/zmk,matrix-transform.yaml
+++ b/app/dts/bindings/zmk,matrix-transform.yaml
@@ -4,6 +4,15 @@ description: |
 compatible: "zmk,matrix-transform"
 
 properties:
+  columns:
+    type: int
+    required: true
+  rows:
+    type: int
+    required: true
+  col-offset:
+    type: int
+    default: 0
   map:
     type: array
     required: true
diff --git a/app/include/zmk/matrix.h b/app/include/zmk/matrix.h
index 9fe1a855..30882638 100644
--- a/app/include/zmk/matrix.h
+++ b/app/include/zmk/matrix.h
@@ -4,6 +4,16 @@
 
 #define ZMK_MATRIX_NODE_ID DT_CHOSEN(zmk_kscan)
 
+#if DT_HAS_CHOSEN(zmk_matrix_transform)
+
+#define ZMK_KEYMAP_TRANSFORM_NODE DT_CHOSEN(zmk_matrix_transform)
+#define ZMK_KEYMAP_LEN DT_PROP_LEN(ZMK_KEYMAP_TRANSFORM_NODE, map)
+
+#define ZMK_MATRIX_ROWS DT_PROP(ZMK_KEYMAP_TRANSFORM_NODE,rows)
+#define ZMK_MATRIX_COLS DT_PROP(ZMK_KEYMAP_TRANSFORM_NODE,columns)
+
+#else /* DT_HAS_CHOSEN(zmk_matrix_transform) */
+
 #if DT_NODE_HAS_PROP(ZMK_MATRIX_NODE_ID,row_gpios)
 #define ZMK_MATRIX_ROWS DT_PROP_LEN(ZMK_MATRIX_NODE_ID,row_gpios)
 #define ZMK_MATRIX_COLS DT_PROP_LEN(ZMK_MATRIX_NODE_ID,col_gpios)
@@ -15,3 +25,6 @@
 #define ZMK_MATRIX_COLS DT_PROP(ZMK_MATRIX_NODE_ID,columns)
 #endif
 
+#define ZMK_KEYMAP_LEN (ZMK_MATRIX_COLS * ZMK_MATRIX_ROWS)
+
+#endif /* !DT_HAS_CHOSEN(zmk_matrix_transform) */
\ No newline at end of file
diff --git a/app/src/keymap.c b/app/src/keymap.c
index dd0fee47..f951dd7f 100644
--- a/app/src/keymap.c
+++ b/app/src/keymap.c
@@ -26,7 +26,7 @@ static u8_t zmk_keymap_layer_default = 0;
 #define TRANSFORMED_LAYER(idx) \
   { UTIL_LISTIFY(DT_PROP_LEN(DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, idx), bindings), _TRANSFORM_ENTRY, idx) }
 
-static struct zmk_behavior_binding zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_COLS] = {
+static struct zmk_behavior_binding zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_KEYMAP_LEN] = {
 #if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 0)
 	TRANSFORMED_LAYER(0),
 #endif
diff --git a/app/src/matrix_transform.c b/app/src/matrix_transform.c
index 7e8b481e..7ecf1ae0 100644
--- a/app/src/matrix_transform.c
+++ b/app/src/matrix_transform.c
@@ -4,11 +4,7 @@
 #include <zmk/matrix.h>
 #include <dt-bindings/zmk/matrix-transform.h>
 
-#define HAS_TRANSFORM DT_HAS_CHOSEN(zmk_matrix_transform)
-
-#if HAS_TRANSFORM
-#define ZMK_KEYMAP_TRANSFORM_NODE DT_CHOSEN(zmk_matrix_transform)
-#define ZMK_KEYMAP_LEN DT_PROP_LEN(ZMK_KEYMAP_TRANSFORM_NODE, map)
+#ifdef ZMK_KEYMAP_TRANSFORM_NODE
 
 #define _TRANSFORM_ENTRY(i, _) \
 	[(KT_ROW(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i)) * ZMK_MATRIX_COLS) + KT_COL(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i))] = i,
@@ -20,11 +16,21 @@ static u32_t transform[] =
 
 u32_t zmk_matrix_transform_row_column_to_position(u32_t row, u32_t column)
 {
-    u32_t matrix_index = (row * ZMK_MATRIX_COLS) + column;
+    u32_t matrix_index;
 
-#if HAS_TRANSFORM
+#if DT_NODE_HAS_PROP(ZMK_KEYMAP_TRANSFORM_NODE, col_offset)
+    column += DT_PROP(ZMK_KEYMAP_TRANSFORM_NODE, col_offset);
+#endif
+
+#if DT_NODE_HAS_PROP(ZMK_KEYMAP_TRANSFORM_NODE, row_offset)
+    row += DT_PROP(ZMK_KEYMAP_TRANSFORM_NODE, row_offset);
+#endif
+
+    matrix_index = (row * ZMK_MATRIX_COLS) + column;
+
+#ifdef ZMK_KEYMAP_TRANSFORM_NODE
     return transform[matrix_index];
 #else
     return matrix_index;
-#endif /* HAS_TRANSFORM */
+#endif /* ZMK_KEYMAP_TRANSFORM_NODE */
 };