From 0f49536b413a81aedb9635c7b2613ca5a8d554c4 Mon Sep 17 00:00:00 2001
From: menschel <menschel.p@posteo.de>
Date: Wed, 30 Dec 2020 21:55:34 +0100
Subject: [PATCH] Add overlay for Seeed Studio CAN BUS FD HAT (#4034)

This patch adds the overlay for the Seeed Studio CAN BUS FD HAT
with two CAN FD Channels and an RTC.
https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html

The overlay was generated by
ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 \
           mcp251xfd-overlay.dts,spi0-1,interrupt=24 \
           i2c-rtc-overlay.dts,pcf85063


Also, add description on how to generate overlays

Signed-off-by: Patrick Menschel <menschel.p@posteo.de>
---
 arch/arm/boot/dts/overlays/Makefile           |   1 +
 arch/arm/boot/dts/overlays/README             |  46 +++++++
 .../dts/overlays/seeed-can-fd-hat-overlay.dts | 117 ++++++++++++++++++
 3 files changed, 164 insertions(+)
 create mode 100644 arch/arm/boot/dts/overlays/seeed-can-fd-hat-overlay.dts

--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -161,6 +161,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
 	sc16is752-spi1.dtbo \
 	sdhost.dtbo \
 	sdio.dtbo \
+	seeed-can-fd-hat.dtbo \
 	sh1106-spi.dtbo \
 	smi.dtbo \
 	smi-dev.dtbo \
--- a/arch/arm/boot/dts/overlays/README
+++ b/arch/arm/boot/dts/overlays/README
@@ -81,6 +81,44 @@ Parameters usually have default values,
 mandatory. See the list of overlays below for a description of the parameters
 and their defaults.
 
+Making new Overlays based on existing Overlays
+==============================================
+
+Recent overlays have been designed in a more general way, so that they can be
+adapted to hardware by changing their parameters. When you have additional
+hardware with more than one device of a kind, you end up using the same overlay
+multiple times with other parameters, e.g.
+
+    # 2 CAN FD interfaces on spi but with different pins
+    dtoverlay=mcp251xfd,spi0-0,interrupt=25
+    dtoverlay=mcp251xfd,spi0-1,interrupt=24
+
+    # a realtime clock on i2c
+    dtoverlay=i2c-rtc,pcf85063
+
+While this approach does work, it requires knowledge about the hardware design.
+It is more feasible to simplify things for the end user by providing a single
+overlay as it is done the traditional way.
+
+A new overlay can be generated by using ovmerge utility.
+https://github.com/raspberrypi/utils/blob/master/ovmerge/ovmerge
+
+To generate an overlay for the above configuration we pass the configuration
+to ovmerge and add the -c flag.
+
+    ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 \
+               mcp251xfd-overlay.dts,spi0-1,interrupt=24 \
+               i2c-rtc-overlay.dts,pcf85063 \
+    >> merged-overlay.dts
+
+The -c option writes the command above as a comment into the overlay as
+a marker that this overlay is generated and how it was generated.
+After compiling the overlay it can be loaded in a single line.
+
+    dtoverlay=merged
+
+It does the same as the original configuration but without parameters.
+
 The Overlay and Parameter Reference
 ===================================
 
@@ -2466,6 +2504,14 @@ Info:   This overlay is now deprecated.
 Load:   <Deprecated>
 
 
+Name:   seeed-can-fd-hat
+Info:   Overlay for Seeed Studio CAN BUS FD HAT with two CAN FD channels and an
+        RTC.
+        https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html
+Load:   dtoverlay=seeed-can-fd-hat
+Params: <None>
+
+
 Name:   sh1106-spi
 Info:   Overlay for SH1106 OLED via SPI using fbtft staging driver.
 Load:   dtoverlay=sh1106-spi,<param>=<val>
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/seeed-can-fd-hat-overlay.dts
@@ -0,0 +1,117 @@
+// redo: ovmerge -c mcp251xfd-overlay.dts,spi0-0,interrupt=25 mcp251xfd-overlay.dts,spi0-1,interrupt=24 i2c-rtc-overlay.dts,pcf85063
+
+// Device tree overlay for https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html 
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/bcm2835.h>
+
+/ {
+	compatible = "brcm,bcm2835";
+	fragment@0 {
+		target = <&spidev0>;
+		__overlay__ {
+			status = "disabled";
+		};
+	};
+	fragment@1 {
+		target = <&gpio>;
+		__overlay__ {
+			mcp251xfd_pins: mcp251xfd_spi0_0_pins {
+				brcm,pins = <25>;
+				brcm,function = <BCM2835_FSEL_GPIO_IN>;
+			};
+		};
+	};
+	fragment@2 {
+		target-path = "/clocks";
+		__overlay__ {
+			clk_mcp251xfd_osc: mcp251xfd-spi0-0-osc {
+				#clock-cells = <0>;
+				compatible = "fixed-clock";
+				clock-frequency = <40000000>;
+			};
+		};
+	};
+	fragment@3 {
+		target = <&spi0>;
+		__overlay__ {
+			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			mcp251xfd@0 {
+				compatible = "microchip,mcp251xfd";
+				reg = <0>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&mcp251xfd_pins>;
+				spi-max-frequency = <20000000>;
+				interrupt-parent = <&gpio>;
+				interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
+				clocks = <&clk_mcp251xfd_osc>;
+			};
+		};
+	};
+	fragment@4 {
+		target = <&spidev1>;
+		__overlay__ {
+			status = "disabled";
+		};
+	};
+	fragment@5 {
+		target = <&gpio>;
+		__overlay__ {
+			mcp251xfd_pins_1: mcp251xfd_spi0_1_pins {
+				brcm,pins = <24>;
+				brcm,function = <BCM2835_FSEL_GPIO_IN>;
+			};
+		};
+	};
+	fragment@6 {
+		target-path = "/clocks";
+		__overlay__ {
+			clk_mcp251xfd_osc_1: mcp251xfd-spi0-1-osc {
+				#clock-cells = <0>;
+				compatible = "fixed-clock";
+				clock-frequency = <40000000>;
+			};
+		};
+	};
+	fragment@7 {
+		target = <&spi0>;
+		__overlay__ {
+			status = "okay";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			mcp251xfd@1 {
+				compatible = "microchip,mcp251xfd";
+				reg = <1>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&mcp251xfd_pins_1>;
+				spi-max-frequency = <20000000>;
+				interrupt-parent = <&gpio>;
+				interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
+				clocks = <&clk_mcp251xfd_osc_1>;
+			};
+		};
+	};
+	fragment@8 {
+		target = <&i2cbus>;
+		__overlay__ {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pcf85063@51 {
+				compatible = "nxp,pcf85063";
+				reg = <0x51>;
+			};
+		};
+	};
+	fragment@9 {
+		target = <&i2c_arm>;
+		i2cbus: __overlay__ {
+			status = "okay";
+		};
+	};
+};
