Linux内核中设备驱动程序与设备节点的匹配(设备树、pinctrl、platform驱动)

源码

本文主要是对.dts .dtsi pinctrl.c文件的简单分析记录。

vs680-a0-evk.dts

// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
 * Copyright (C) 2020 Synaptics Incorporated
 *
 * Author: Jisheng Zhang <jszhang@kernel.org>
 */

/dts-v1/;

/memreserve/ 0x7f000000 0x01000000;

#include <dt-bindings/gpio/gpio.h>

#include "vs680-a0.dtsi"

/ {
	model = "Synaptics VS680 EVK";
	compatible = "syna,vs680-evk", "syna,vs680";

	aliases {
		i2c3 = &i2cdemux3_i2c;
	};

	cpus {
		cpu@0 {
			cpu0-supply = <&vcpu>;
		};
	};

	chosen {
		stdout-path = "serial0:115200n8";
	};

	memory {
		device_type = "memory";
		reg = <0 0x01000000 0 0x7f000000>;
	};

	reserved-memory {
		#address-cells = <2>;
		#size-cells = <2>;
		ranges;

		ramoops@f901c000{
			compatible = "ramoops";
			reg = <0x0 0xf901c000 0x0 0x4000>;
			record-size = <0x4000>;
		};
	};

	panel0-backlight {
		compatible = "pwm-backlight";
		pinctrl-names = "default";
		pinctrl-0 = <&pwm1_pmux>;
		pwms = <&pwm0 1 1000000 0>;
		brightness-levels = <0 36 72 108 144 180 212 255>;
		default-brightness-level = <6>;
		enable-gpio = <&expander3 2 GPIO_ACTIVE_HIGH>;
		status = "okay";
	};

	ion {
		compatible = "syna,ion-berlin-heaps";
		pool-num = <2>;
		reg-names = "NonSecure", "Secure";
		reg = <0 0x7f000000 0 0x00800000>,
		      <0 0x7f800000 0 0x00800000>;
		attributes-num-per-pool = <2>;
		pool-attributes = <0x00000105 0x00000F3A 0x00000102 0x00000F3D>;
	};

	regulators {
		compatible = "simple-bus";
		#address-cells = <1>;
		#size-cells = <0>;

		vmmc_sdhci1: vmmc_sdhci1 {
			compatible = "regulator-fixed";
			regulator-min-microvolt = <3300000>;
			regulator-max-microvolt = <3300000>;
			regulator-name = "vmmc_sdio";
			enable-active-high;
			gpio = <&expander3 1 GPIO_ACTIVE_HIGH>;
		};

		reg_usb0_vbus: usb0_vbus {
			compatible = "regulator-fixed";
			regulator-name = "usb0_vbus";
			regulator-min-microvolt = <5000000>;
			regulator-max-microvolt = <5000000>;
			gpio = <&expander1 3 GPIO_ACTIVE_LOW>;
			enable-active-high;
		};

		reg_xhci0_vbus: xhci0_vbus {
			compatible = "regulator-fixed";
			regulator-name = "xhci0_vbus";
			regulator-min-microvolt = <5000000>;
			regulator-max-microvolt = <5000000>;
			gpio = <&expander1 5 GPIO_ACTIVE_LOW>;
			enable-active-high;
		};
	};

	dummy_label {
		dummy1 = <&vcpu1>;
		dummy2 = <&vcore1>;
	};

	bt_reg_on: bt_reg_on {
		compatible = "syna,rfkill";
		bt-power-gpio = <&expander1 6 GPIO_ACTIVE_HIGH>;
	};

	bluesleep: bluesleep {
		compatible = "syna,bluesleep";
		bt-dev-wake-gpio = <&portd 17 GPIO_ACTIVE_HIGH>;
	};

	gpioi2c3: gpioi2c3 {
		#address-cells = <1>;
		#size-cells = <0>;
		compatible = "i2c-gpio";
		gpios = <&portd 10 GPIO_ACTIVE_HIGH /* sda */
			 &portd 9 GPIO_ACTIVE_HIGH /* scl */
			>;
		i2c-gpio,delay-us = <5>;
	};

	i2cdemux3 {
		compatible = "i2c-dyndmx-pinctrl";
		#address-cells = <1>;
		#size-cells = <0>;

		i2c-parent = <&i2c3>, <&gpioi2c3>;

		pinctrl-names = "i2c3", "gpioi2c3";
		pinctrl-0 = <&i2c3_pmux>;
		pinctrl-1 = <&gpioi2c3_pmux>;

		i2cdemux3_i2c: i2c@0 {
			reg = <0>;
			#address-cells = <1>;
			#size-cells = <0>;

			expander0: gpio@43 {
				compatible = "fcs,fxl6408";
				reg = <0x43>;
				gpio-controller;
				#gpio-cells = <2>;
			};

			expander1: gpio@44 {
				compatible = "fcs,fxl6408";
				reg = <0x44>;
				gpio-controller;
				#gpio-cells = <2>;
			};

			rtc0: rtc@68 {
				compatible = "dallas,ds1339";
				wakeup-source;
				reg = <0x68>;
			};
		};

		i2c@1 {
			reg = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
		};
	};
};

&pinctrl {
	gmac0_pmux: gmac0-pmux {
		groups = "RGMII_MDC", "RGMII_MDIO", "RGMII_TXC", "RGMII_TXD0", "RGMII_TXD1", "RGMII_TXD2", "RGMII_TXD3", "RGMII_TXCTL", "RGMII_RXC", "RGMII_RXD0", "RGMII_RXD1", "RGMII_RXD2", "RGMII_RXD3", "RGMII_RXCTL";
		function = "rgmii";
		drive-strength = <3>;
	};

	i2c0_pmux: i2c0-pmux {
		groups = "TW0_SCL", "TW0_SDA";
		function = "tw0";
		drive-strength = <7>;
	};

	i2c1_pmux: i2c1-pmux {
		groups = "SPI1_SS2n", "SPI1_SS3n";
		function = "tw1b";
		drive-strength = <3>;
	};

	sdhci1_pmux: sdhci1-pmux {
		groups = "SDIO_CDn";
		function = "sdio";
		drive-strength = <7>;
	};

	expander3_pmux: expander3-pmux {
		groups = "USB2_DRV_VBUS";
		function = "gpio";
	};

	pwm1_pmux: pwm1-pmux {
		groups = "SPI1_SS1n";
		function = "pwm";
	};
	
	uart3_pmux: uart3-pmux {
		groups = "STS0_CLK", "STS0_SOP";
		function = "uart3";
		drive-strength = <7>;
	};
};

&sm_pinctrl {
	i2c2_pmux: i2c2-pmux {
		groups = "SM_URT1_TXD", "SM_URT1_RXD";
		function = "tw2b";
		drive-strength = <7>;
	};

	i2c3_pmux: i2c3-pmux {
		groups = "SM_TW3_SCL", "SM_TW3_SDA";
		function = "tw3";
		drive-strength = <7>;
	};

	uart2_pmux: uart2-pmux {
		groups = "SM_SPI2_SS2n", "SM_SPI2_SS3n", "SM_SPI2_SDI", "SM_SPI2_SDO";
		function = "uart2";
		drive-strength = <3>;
	};

	gpioi2c3_pmux: gpioi2c3-pmux {
		groups = "SM_TW3_SCL", "SM_TW3_SDA";
		function = "gpio";
		drive-strength = <7>;
	};

	hrx5v_pmux: hrx5v-pmux {
		groups = "SM_HDMIRX_PWR5V";
		function = "gpio";
		drive-strength = <7>;
	};
};

&avio_pinctrl {
	i2s1_pmux: i2s1-pmux {
		groups = "I2S1_BCLKIO", "I2S1_LRCKIO", "I2S1_DO0", "I2S1_MCLK";
		function = "i2s1";
	};

	i2s2_pmux: i2s2-pmux {
		groups = "I2S2_BCLKIO", "I2S2_LRCKIO", "I2S2_DI0";
		function = "i2s2";
	};

	falcon_gpio_pmux: falcon_gpio-pmux {
		groups = "I2S1_DO1";
		function = "gpio";
	};

	i2s3_pmux: i2s3-pmux {
		groups = "I2S3_LRCKIO", "I2S3_BCLKIO", "I2S3_DI";
		function = "i2s3";
	};

	pdm_pmux: pdm-pmux {
		groups = "I2S2_MCLK", "I2S2_DI3", "I2S2_DI2";
		function = "pdm";
	};

	spdifo_pmux: spdifo-pmux {
		groups = "SPDIFO";
		function = "spdifo";
	};

	spdifi_pmux: spdifi-pmux {
		groups = "SPDIFI";
		function = "spdifi";
	};

};

&sdhci0 {
	status = "okay";
	sdclkdl-dc = /bits/ 8 <26>;
	mmc-ddr-1_8v;
	mmc-hs200-1_8v;
	mmc-hs400-1_8v;
	dll-calibration;
	pad-sp = /bits/ 8 <14>;
	pad-sn = /bits/ 8 <14>;
};

&sdhci1 {
	status = "okay";
	pinctrl-0 = <&sdhci1_pmux>;
	pinctrl-names = "default";
	no-sdio;
	no-mmc;
	disable-wp;
	sdclkdl-dc = /bits/ 8 <75>;
	pad-sp = /bits/ 8 <12>;
	pad-sn = /bits/ 8 <12>;
	vmmc-supply = <&vmmc_sdhci1>;
};

&pcie_phy0 {
	status = "okay";
};

&pcie0 {
	status = "okay";
	reset-gpios = <&expander1 1 GPIO_ACTIVE_LOW>;
};

&i2c0 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&i2c0_pmux>;
	no-irq-suspend;

	falcon: cx9000@33 {
		compatible = "cnxt,cx9000";
		pinctrl-names = "default";
		pinctrl-0 = <&falcon_gpio_pmux>;

		#sound-dai-cells = <0>;
		reg = <0x33>;
		enable-gpios=<&porta 17 GPIO_ACTIVE_HIGH>;
		status = "okay";
	};

	expander2: gpio@43 {
		compatible = "fcs,fxl6408";
		reg = <0x43>;
		gpio-controller;
		#gpio-cells = <2>;
		shutdown-mask = /bits/ 8 <0x1>;
		shutdown-val = /bits/ 8 <0x0>;

		soc_global_rstn {
			gpio-hog;
			gpios = <0 GPIO_ACTIVE_HIGH>;
			output-high;
		};
	};

	expander3: gpio@44 {
		compatible = "fcs,fxl6408";
		pinctrl-names = "default";
		pinctrl-0 = <&expander3_pmux>;
		reg = <0x44>;
		gpio-controller;
		#gpio-cells = <2>;
		interrupt-parent = <&portb>;
		interrupts = <23 IRQ_TYPE_NONE>;
		interrupt-controller;
		#interrupt-cells = <2>;
		#address-cells = <0>;
	};

	fts_ts@38 {
		compatible = "focaltech,fts";
		status = "okay";
		reg = <0x38>;
		interrupt-parent = <&expander3>;
		interrupts = <4 0>;
		focaltech,irq-gpio = <&expander3 4 0>;
		focaltech,reset-gpio = <&expander3 5 GPIO_ACTIVE_LOW>;
		focaltech,display-coords = <0 0 799 1279>;
		focaltech,max-touch-number = <5>;
	};

	backlight@2c {
		compatible = "ti,lp8556";
		reg = <0x2c>;
		bl-name = "lcd-bl";
		dev-ctrl = /bits/ 8 <0x05>;
		init-brt = /bits/ 8 <0xFF>;
		pwm-period = /bits/ 8 <0x00>;

		/* CFG2 */
		rom_A2h {
			rom-addr = /bits/ 8 <0xA2>;
			rom-val = /bits/ 8 <0x28>;
		};
	};
};

&i2c1 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&i2c1_pmux>;

	vcpu: regulator@62 {
		compatible = "mps,mp8867";
		regulator-name = "vcpu";
		regulator-min-microvolt = <700000>;
		regulator-max-microvolt = <980000>;
		regulator-always-on;
		regulator-boot-on;
		enable-gpios = <&expander0 1 GPIO_ACTIVE_LOW>;
		mps,fb-voltage-divider = <80 240>;
		regulator-active-discharge = <0>;
		mps,switch-frequency-hz = <1500000>;
		mps,vsel-step = <1>;
		reg = <0x62>;
	};

	vcpu1: regulator1@60 {
		status = "disabled";
		compatible = "silergy,sy8827n";
		regulator-name = "vcpu";
		regulator-min-microvolt = <700000>;
		regulator-max-microvolt = <987500>;
		regulator-always-on;
		regulator-boot-on;
		regulator-active-discharge = <0>;
		enable-gpios = <&expander0 1 GPIO_ACTIVE_LOW>;
		silergy,vsel-step = <1>;
		reg = <0x60>;
	};
};

&i2c2 {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&i2c2_pmux>;

	vcore: regulator@60 {
		compatible = "mps,mp8869";
		regulator-name = "vcore";
		regulator-min-microvolt = <700000>;
		regulator-max-microvolt = <900000>;
		regulator-always-on;
		regulator-boot-on;
		enable-gpios = <&expander0 0 GPIO_ACTIVE_LOW>;
		mps,fb-voltage-divider = <80 240>;
		regulator-active-discharge = <0>;
		mps,switch-frequency-hz = <1250000>;
		mps,vsel-step = <1>;
		regulator-ramp-delay = <40000>;
		reg = <0x60>;
	};

	vcore1: regulator1@60 {
		status = "disabled";
		compatible = "silergy,sy8827n";
		regulator-name = "vcore";
		regulator-min-microvolt = <700000>;
		regulator-max-microvolt = <937500>;
		regulator-always-on;
		regulator-boot-on;
		regulator-active-discharge = <0>;
		enable-gpios = <&expander0 0 GPIO_ACTIVE_LOW>;
		silergy,vsel-step = <1>;
		reg = <0x60>;
	};
};

&i2c3 {
	status = "okay";
	no-irq-suspend;
};

&uart0 {
	status = "okay";
};

&uart3 {
	status = "okay";
};

&uart2 {
	status = "okay";
	pinctrl-0 = <&uart2_pmux>;
	pinctrl-names = "default";
};

&npu {
	status = "okay";
};

&usb0 {
	vbus-supply = <&reg_usb0_vbus>;
	status = "okay";
};

&usb_phy0  {
	status = "okay";
};

&xhci0 {
	vbus-supply = <&reg_xhci0_vbus>;
	status = "okay";
};

&usb_phy1  {
	status = "okay";
};

&mdio0 {
	phy0: ethernet-phy@0 {
		reg = <0>;
	};
};

&gmac0 {
	status = "okay";
	pinctrl-0 = <&gmac0_pmux>;
	pinctrl-names = "default";
	phy-handle = <&phy0>;
	phy-mode = "rgmii-id";
	snps,reset-gpio = <&expander1 0 GPIO_ACTIVE_LOW>;
	snps,reset-delays-us = <0 10000 50000>;
};

&sm {
	status = "okay";
};

&ir {
	status = "okay";
};

&isp {
	status = "okay";
	enable-gpios = <&porta 15 GPIO_ACTIVE_HIGH>;
	i2c-bus = <&i2c3>;
	dev-addr = <112>;
};

&vpp {
	status = "okay";
};

&fb {
	status = "okay";
};

&tsp {
	status = "okay";
};

&h1 {
	status = "okay";
};

&vxg {
	status = "okay";
};

&shm {
	status = "okay";
};

&bm {
	status = "okay";
};

&msg {
	status = "okay";
};

&drm {
	status = "okay";
};

&avio {
	status = "okay";
	vpp {
		hdtx5v-gpio = <&portd 16 GPIO_ACTIVE_HIGH>;
		mipirst-gpio = <&expander3 5 GPIO_ACTIVE_LOW>;
	};
};

&cec {
	status = "okay";
};

&axi_mc0 {
	status = "okay";
};

&gpu {
	status = "okay";
};

&aout {
	status = "okay";
};

&hrx {
	status = "okay";
	pinctrl-0 = <&hrx5v_pmux>;
	pinctrl-names = "default";
	hrxhpd-gpio = <&expander1 4 GPIO_ACTIVE_HIGH>;
	hrx5v-gpio = <&portd 21 GPIO_ACTIVE_HIGH>;
};

&i2s_pri {
	status = "okay";
	pinctrl-0 = <&i2s1_pmux>;
	pinctrl-names = "default";
};

&spdif_out {
	status = "okay";
	pinctrl-0 = <&spdifo_pmux>;
	pinctrl-names = "default";
};

&i2s_mic1 {
	status = "okay";
	pinctrl-0 = <&i2s2_pmux>;
	pinctrl-names = "default";
	intlmode;
};

&dmic {
	status = "okay";
	pinctrl-0 = <&pdm_pmux>;
	pinctrl-names = "default";
	pdm-data-sel-gpio = <&expander2 4 GPIO_ACTIVE_HIGH>;
	pdm-type = <1>;
	pdm-clk-sel = <2>;
};

&i2s_mic2 {
	status = "okay";
	pinctrl-0 = <&i2s3_pmux>;
	pinctrl-names = "default";
	slave;
	invertbclk;
};

&i2s_mic6 {
	status = "okay";
};

&i2s_pri_lpbk {
	status = "okay";
};

&i2s_hdmi_lpbk {
	status = "okay";
};

&hdmi_out {
	status = "okay";
};

&vs680_spdifi {
	status = "okay";
	pinctrl-0 = <&spdifi_pmux>;
	pinctrl-names = "default";
	gate-gpio = <&expander2 4 GPIO_ACTIVE_HIGH>;
	enable-gpio = <&expander3 7 GPIO_ACTIVE_LOW>;
	dynamic-src-ctrl;
};

&vs680_pcm {
	status = "okay";
};

&vs680_asoc {
	status = "okay";

	soc_i2so1: soc-i2so1 {
		status = "okay";
		stream-name = "soc-i2so1";
		link-name = "soc-i2so1";
		format = "i2s";
		continuous-clock;
		bitclock-inversion;
		frame-inversion;
		bitclock-master;
		frame-master;
		cpu-node = <&i2s_pri>;
		codec-name = "cx9000.0-0033";
		codec-dai-name = "cx9000-amplifier";
		platform-node = <&vs680_pcm>;
	};

	soc_spdifo: soc-spdifo {
		status = "okay";
		stream-name = "soc-spdifo";
		link-name = "soc-spdifo";
		cpu-node = <&spdif_out>;
		codec-name = "snd-soc-dummy";
		codec-dai-name = "snd-soc-dummy-dai";
		platform-node = <&vs680_pcm>;
	};

	soc_dmic: soc-dmic {
		status = "okay";
		stream-name = "soc-dmic";
		link-name = "soc-dmic";
		cpu-node = <&dmic>;
		codec-name = "snd-soc-dummy";
		codec-dai-name = "snd-soc-dummy-dai";
		platform-node = <&vs680_pcm>;
	};

	soc_i2si: soc-i2si2 {
		status = "okay";
		stream-name = "soc-i2si2";
		link-name = "soc-i2si2";
		format = "i2s";
		cpu-node = <&i2s_mic1>;
		codec-name = "snd-soc-dummy";
		codec-dai-name = "snd-soc-dummy-dai";
		platform-node = <&vs680_pcm>;
	};

	soc_i2si3: soc-i2si3 {
		status = "okay";
		stream-name = "soc-i2si3";
		link-name = "soc-i2si3";
		format = "i2s";
		cpu-node = <&i2s_mic2>;
		codec-name = "snd-soc-dummy";
		codec-dai-name = "snd-soc-dummy-dai";
		platform-node = <&vs680_pcm>;
	};

	soc_i2s_pri_lpbk: soc-i2s-pri-lpbk {
		status = "okay";
		stream-name = "soc-i2s-pri-lpbk";
		link-name = "soc-i2s-pri-lpbk";
		format = "i2s";
		cpu-node = <&i2s_pri_lpbk>;
		codec-name = "snd-soc-dummy";
		codec-dai-name = "snd-soc-dummy-dai";
		platform-node = <&vs680_pcm>;
	};

	soc_i2s_hdmi_lpbk: soc-i2s-hdmi-lpbk {
		status = "okay";
		stream-name = "soc-i2s-hdmi-lpbk";
		link-name = "soc-i2s-hdmi-lpbk";
		format = "i2s";
		cpu-node = <&i2s_hdmi_lpbk>;
		codec-name = "snd-soc-dummy";
		codec-dai-name = "snd-soc-dummy-dai";
		platform-node = <&vs680_pcm>;
	};

	soc_spdifi: soc-spdifi {
		status = "okay";
		stream-name = "soc-spdifi";
		link-name = "soc-spdifi";
		cpu-node = <&vs680_spdifi>;
		codec-name = "snd-soc-dummy";
		codec-dai-name = "snd-soc-dummy-dai";
		platform-node = <&vs680_pcm>;
	};

	soc_i2s_earc: soc-i2s-earc {
		status = "okay";
		stream-name = "soc-i2s-earc";
		link-name = "soc-i2s-earc";
		format = "i2s";
		bitclock-master;
		frame-master;
		cpu-node = <&i2s_mic6>;
		codec-name = "snd-soc-dummy";
		codec-dai-name = "snd-soc-dummy-dai";
		platform-node = <&vs680_pcm>;
	};

        soc_hdmio: soc-hdmio {
                status = "okay";
                stream-name = "soc-hdmio";
                link-name = "soc-hdmio";
                format = "i2s";
                cpu-node = <&hdmi_out>;
                codec-name = "snd-soc-dummy";
                codec-dai-name = "snd-soc-dummy-dai";
                platform-node = <&vs680_pcm>;
        };
};

&ovp {
	status = "okay";
};

&pwm0 {
	status = "okay";
};

&mc_dfc {
	status = "okay";
};

vs680-a0.dtsi

// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
 * Copyright (C) 2019 Synaptics Incorporated
 *
 * Author: Jisheng Zhang <jszhang@kernel.org>
 */

#include <dt-bindings/clock/vs680.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>

/ {
	compatible = "syna,vs680";
	interrupt-parent = <&gic>;
	#address-cells = <2>;
	#size-cells = <2>;

	aliases {
		serial0 = &uart0;
		serial1 = &uart1;
		serial2 = &uart2;
		serial3 = &uart3;
		i2c0 = &i2c0;
		i2c1 = &i2c1;
		i2c2 = &i2c2;
		i2c3 = &i2c3;
	};

	psci {
		compatible = "arm,psci-0.2";
		method = "smc";
	};

	cpus {
		#address-cells = <1>;
		#size-cells = <0>;

		cpu0: cpu@0 {
			compatible = "arm,cortex-a73";
			device_type = "cpu";
			reg = <0x0>;
			enable-method = "psci";
			next-level-cache = <&l2>;
			cpu-idle-states = <&CPU_SLEEP_0>;
			operating-points-v2 = <&cpu_opp_table>;
			clocks = <&cpupll 0>;
		};

		cpu1: cpu@1 {
			compatible = "arm,cortex-a73";
			device_type = "cpu";
			reg = <0x1>;
			enable-method = "psci";
			next-level-cache = <&l2>;
			cpu-idle-states = <&CPU_SLEEP_0>;
			operating-points-v2 = <&cpu_opp_table>;
			clocks = <&cpupll 0>;
		};

		cpu2: cpu@2 {
			compatible = "arm,cortex-a73";
			device_type = "cpu";
			reg = <0x2>;
			enable-method = "psci";
			next-level-cache = <&l2>;
			cpu-idle-states = <&CPU_SLEEP_0>;
			operating-points-v2 = <&cpu_opp_table>;
			clocks = <&cpupll 0>;
		};

		cpu3: cpu@3 {
			compatible = "arm,cortex-a73";
			device_type = "cpu";
			reg = <0x3>;
			enable-method = "psci";
			next-level-cache = <&l2>;
			cpu-idle-states = <&CPU_SLEEP_0>;
			operating-points-v2 = <&cpu_opp_table>;
			clocks = <&cpupll 0>;
		};

		l2: l2-cache0 {
			compatible = "cache";
		};

		idle-states {
			entry-method = "psci";
			CPU_SLEEP_0: cpu-sleep-0 {
				compatible = "arm,idle-state";
				local-timer-stop;
				arm,psci-suspend-param = <0x0010000>;
				entry-latency-us = <75>;
				exit-latency-us = <155>;
				min-residency-us = <50000>;
			};
		};

		cpu_opp_table: opp_table0 {
			compatible = "operating-points-v2";
			opp-shared;

			opp@800000000 {
				opp-hz = /bits/ 64 <800000000>;
				opp-microvolt = <800000 800000 900000>;
				clock-latency-ns = <12600000>;
			};

			opp@1400000000 {
				opp-hz = /bits/ 64 <1400000000>;
				opp-microvolt = <800000 800000 900000>;
				clock-latency-ns = <12600000>;
			};

			opp@1800000000 {
				opp-hz = /bits/ 64 <1800000000>;
				opp-microvolt = <800000 800000 900000>;
				clock-latency-ns = <12600000>;
				opp-suspend;
			};

			opp@2100000000 {
				opp-hz = /bits/ 64 <2100000000>;
				opp-microvolt = <900000 900000 900000>;
				clock-latency-ns = <12600000>;
			};
		};
	};

	osc: osc {
		compatible = "fixed-clock";
		#clock-cells = <0>;
		clock-frequency = <25000000>;
	};

	pmu {
		compatible = "arm,cortex-a73-pmu";
		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
			     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
			     <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
			     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
		interrupt-affinity = <&cpu0>,
				     <&cpu1>,
				     <&cpu2>,
				     <&cpu3>;
	};

	timer {
		compatible = "arm,armv8-timer";
		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
	};

	soc {
		compatible = "simple-bus";
		#address-cells = <1>;
		#size-cells = <1>;
		ranges = <0 0 0 0xffffffff>;

		h1: h1@f7000000 {
			compatible = "syna,berlin-h1";
			reg = <0xf7000000 0x400000>;
			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
			clocks = <&clk CLK_ENCODER>;
			status = "disabled";
		};

		avio: avio@f7400000 {
			#address-cells = <1>;
			#size-cells = <1>;
			compatible = "syna,berlin-avio";
			reg = <0xf7400000 0x200000>;
			ranges = <0 0xf7400000 0x200000>;
			status = "disabled";

			dhub {
				compatible = "syna,berlin-dhub";
				frame-rate = <60>;
				interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
				interrupt-names = "vpp_dhub";
			};

			aio {
				compatible = "syna,berlin-aio";
				reg = <0xAC000 0x400>, <0x98000 0x8000>;
				reg-names = "aio_base", "gbl_base";
				clocks = <&clk CLK_AIOSYS>, <&apll0 0>, <&apll1 0>;
				clock-names = "aio_sysclk", "audio0_clk", "audio1_clk";
			};

			vpp {
				compatible = "syna,berlin-vpp";
				clocks = <&vpll0 0>, <&vpll1 0>,
					<&clk CLK_AIOSYS>, <&clk CLK_TXESC>;
				clock-names = "avio_vclk0", "avio_dpiclk",
					"aio_sysclk", "avio_txescclk";
			};
		};

		vpll0: vpll0 {
			compatible = "syna,vs680-pll";
			reg = <0xf749c004 0x20>, <0xf749c138 0x4>;
			#clock-cells = <1>;
			clocks = <&osc>;
			bypass-shift = /bits/ 8 <0>;
			pd-bypass;
		};

		apll0: apll0 {
			compatible = "syna,vs680-pll";
			reg = <0xf749c028 0x20>, <0xf749c138 0x4>;
			#clock-cells = <1>;
			clocks = <&osc>;
			bypass-shift = /bits/ 8 <2>;
			pd-bypass;
		};

		apll1: apll1 {
			compatible = "syna,vs680-pll";
			reg = <0xf749c04c 0x20>, <0xf749c138 0x4>;
			#clock-cells = <1>;
			clocks = <&osc>;
			bypass-shift = /bits/ 8 <3>;
			pd-bypass;
		};

		vpll1: vpll1 {
			compatible = "syna,vs680-pll";
			reg = <0xf749c070 0x20>, <0xf749c138 0x4>;
			#clock-cells = <1>;
			clocks = <&osc>;
			bypass-shift = /bits/ 8 <1>;
			pd-bypass;
		};

		dhubctr_a: interrupt-controller@f74b8000 {
			compatible = "syna,vs680-dhub-irq";
			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
			reg = <0xf74b8000 0x418>;
			interrupt-controller;
			#interrupt-cells = <1>;
			#address-cells = <0>;
		};

		aout: aout@f74ac000 {
			compatible = "syna,berlin-aout";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <0>, <2>, <7>, <14>;
			interrupt-names = "ma0", "loro", "hdmi", "spdif";
			status = "disabled";
		};

		i2s_pri: i2s-pri {
			compatible = "syna,vs680-i2s-pri";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <0>;
			interrupt-names = "pri";
		};

		i2s_sec: i2s-sec {
			compatible = "syna,vs680-i2s-sec";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <2>;
		};

		spdif_out: spdif-out {
			compatible = "syna,vs680-spdifo";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <14>;
			interrupt-names = "spdifo";
		};

		hdmi_out: hdmi-out {
			compatible = "syna,vs680-hdmi";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <7>;
			interrupt-names = "hdmi";
		};

		i2s_mic1: i2s-mic1 {
			compatible = "syna,vs680-i2s-mic1";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <5>;
		};

		i2s_mic2: i2s-mic2 {
			compatible = "syna,vs680-i2s-mic2";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <6>;
		};

		i2s_mic6: i2s-mic6 {
			compatible = "syna,vs680-i2s-mic6";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <15>;
		};

		i2s_pri_lpbk: i2s_pri_lpbk {
			compatible = "syna,vs680-i2s-pri-lpbk";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <10>;
		};

		i2s_hdmi_lpbk: i2s_hdmi_lpbk {
			compatible = "syna,vs680-i2s-hdmi-lpbk";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <11>;
		};

		pdm_pdmi: pdm-pdmi {
			compatible = "syna,vs680-pdm-pdmi";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <4>;
		};

		dmic: dmic-pdm {
			compatible = "syna,vs680-dmic-pdm";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <4>;
			interleaved-mode;
			interleaved-dummy-data;
		};

		vs680_spdifi: vs680-spdifi {
			compatible = "syna,vs680-spdifi";
			status = "disabled";
			interrupt-parent = <&dhubctr_a>;
			/*Set spdif input margin value
			 *for different sample rate.
			 */
			sample-rate-32000-margin = <0x1F171717>;
			sample-rate-44100-margin = <0x1F171717>;
			sample-rate-48000-margin = <0x1F171717>;
			sample-rate-88000-margin = <0x1A101010>;
			sample-rate-96000-margin = <0x1A101010>;
			sample-rate-17600-margin = <0x0F080808>;
			sample-rate-192000-margin = <0x0F070707>;
			interrupts = <15>;
		};

		vs680_pcm: vs680-pcm {
			compatible = "syna,vs680-pcm";
			status = "disabled";
		};

		vs680_asoc: vs680-asoc {
			compatible = "syna,vs680-asoc";
			status = "disabled";
		};

		hrx: hrx@f74a0000 {
			compatible = "syna,berlin-hrx";
			interrupt-parent = <&dhubctr_a>;
			interrupts = <9>, <23>, <24>, <25>, <26>, <27>;
			interrupt-names = "mic3", "otg", "hdmirx", "ytg", "uvtg", "itg";
			reg = <0xf74a0000 0x8000>, <0xf7fe2400 0x404>;
			reg-names = "hrx_base", "edid_base";
			status = "disabled";
		};

		vxg: vxg@f7600000 {
			compatible = "syna,berlin-vxg";
			reg = <0xf7600000 0x200000>;
			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
			clocks = <&clk CLK_DECODER>;
			status = "disabled";
		};

		ovp: ovp@f78c0000 {
			compatible = "syna,berlin-ovp";
			reg = <0xf78c0000 0x10000>;
			clocks = <&clk CLK_OVPCORE>;
			clock-names = "ovp_coreclk";
			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
			interrupt-names = "ovp_intr";
			status = "disabled";
		};

		gic: interrupt-controller@f7901000 {
			compatible = "arm,gic-400";
			#interrupt-cells = <3>;
			#address-cells = <0>;
			interrupt-controller;
			reg = <0xf7901000 0x1000>,
			      <0xf7902000 0x2000>,
			      <0xf7904000 0x2000>,
			      <0xf7906000 0x2000>;
			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
		};

		hwmon@f7920100 {
			compatible = "syna,vs680-hwmon";
			reg = <0xf7920100 0x14>;
			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
		};

		cpupll: cpupll@f7922000 {
			compatible = "syna,vs680-pll";
			reg = <0xf7922000 0x20>, <0xf7ea0710 0x4>;
			#clock-cells = <1>;
			clocks = <&osc>, <&clk CLK_CPUFASTREF>;
			bypass-shift = /bits/ 8 <4>;
			suspend-resume;
		};

		axi_mc0: axi_meter@f7940000 {
			compatible = "syna,vs680-axi-meter";
			reg = <0xF7940000 0x1000>;
			status = "disabled";
		};

		gpu: gpu@0xf7980000 {
			compatible = "img,powervr";
			reg = <0xf7980000 0x80000>;
			clocks = <&clk CLK_GFX3DCORE>, <&clk CLK_GFX3DSYS>;
			clock-names = "gfx3dcore", "gfx3dsys";
			interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
			operating-points-v2 = <&gpu_opp_table>;
			status = "disabled";
		};

		gpu_opp_table: opp_table1 {
			compatible = "operating-points-v2";
			opp-shared;

			opp@700000000 {
				opp-hz = /bits/ 64 <700000000>;
				clock-latency-ns = <500000>;
			};
		};

		tsp: tsp@f7a40000 {
			compatible = "syna,berlin-tsp";
			clocks = <&clk CLK_TSP>, <&clk CLK_TSPREF>;
			clock-names = "core", "ref";
			interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
			reg = <0xf7a40000 0x40000>;
			status = "disabled";
		};

		shm: shm {
			compatible = "syna,berlin-shm";
			status = "disabled";
		};

		bm: bm {
			compatible = "syna,berlin-bm";
			status = "disabled";
		};

		msg: msg {
			compatible = "syna,berlin-msg";
			status = "disabled";
		};

		drm: drm {
			compatible = "syna,berlin-drm";
			status = "disabled";
		};

		sdhci0: sdhci@f7aa0000 {
			compatible = "snps,dwcmshc-sdhci";
			reg = <0xf7aa0000 0x1000>;
			interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
			clocks = <&clk CLK_EMMC>, <&gateclk CLK_EMMCSYS>;
			clock-names = "core", "bus";
			resets = <&chip 0x680 12 0 0>, <&chip 0x688 6 1 0>;
			reset-names = "host", "phy";
			phy-offset = <0x300>;
			bus-width = <8>;
			non-removable;
			no-sd;
			no-sdio;
			status = "disabled";
		};

		sdhci1: sdhci@f7ab0000 {
			compatible = "snps,dwcmshc-sdhci";
			reg = <0xf7ab0000 0x1000>;
			interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
			clocks = <&clk CLK_SD0>, <&gateclk CLK_SDIOSYS>;
			clock-names = "core", "bus";
			resets = <&chip 0x680 2 0 0 >, <&chip 0x688 5 1 0>;
			reset-names = "host", "phy";
			phy-offset = <0x300>;
			bus-width = <4>;
			status = "disabled";
		};

		gmac0: ethernet@f7b60000 {
			compatible = "snps,dwmac";
			reg = <0xf7b60000 0x2000>;
			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
			interrupt-names = "macirq";
			clocks = <&clk CLK_GETHRGMII>, <&gateclk CLK_GETHRGMIISYS>;
			clock-names = "stmmaceth", "pclk";
			clk_csr = <1>;
			snps,multicast-filter-bins = <128>;
			snps,perfect-filter-entries = <16>;
			status = "disabled";
			mdio0: mdio0 {
				compatible = "snps,dwmac-mdio";
				#address-cells = <1>;
				#size-cells = <0>;
			};
		};

		npu: npu@f7bc0000 {
			compatible = "syna,synap", "vivante,galcore";
			reg = <0xf7bc0000 0x40000>;
			resets = <&chip 0x668 0 1 0>;
			interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
			clocks = <&gateclk CLK_NPUAXI>, <&clk CLK_NPU>;
			clock-names = "sys", "core";
			status = "disabled";
		};

		usb0: usb@f7c00000 {
			compatible = "syna,berlin-usb";
			reg = <0xf7c00000 0x40000>;
			interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
			clocks = <&gateclk 0>;
			clock-names = "otg";
			phys = <&usb_phy0>;
			phy-names = "usb2-phy";
			resets = <&chip 0x688 3 1 0>, <&chip 0x688 4 1 0>, <&chip 0x680 9 0 0>;
			reset-names = "dwc2", "dwc2-ecc", "dwc2-sync";
			dr_mode = "otg";
			g-rx-fifo-size = <512>;
			g-np-tx-fifo-size = <64>;
			g-tx-fifo-size = <256 256 256 256 256 128  64 64
			                   64  64  64  64  64  64  64>;
			status = "disabled";
		};

		usb_phy0: phy@f7c40000 {
			compatible = "syna,vs680-usb2-phy";
			reg = <0xf7c40000 0x100>;
			#phy-cells = <0>;
			resets = <&chip 0x688 2 1 0>;
			reset-names = "phy";
			status = "disabled";
		};

		mc_dfc: mc_dfc@f7cb0000 {
			compatible = "syna,vs680-mc-dfc";
			reg = <0xf7cb0000 0x400>, <0xf7940000 0x400>;
			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
			status = "disabled";
		};

		xhci0: xhci@f7d00000 {
			compatible = "syna,vs680-dwusb3";
			clocks = <&clk CLK_USB3CORE>;
			clock-names = "core_clk";
			resets = <&chip 0x680 10 0 0>;
			reset-names = "rst-sync";
			phys = <&usb_phy1>;
			phy-names = "usb-phy";
			#address-cells = <1>;
			#size-cells = <1>;
			ranges;
			status = "disabled";
			usb_dwc3: dwc3@f7d00000 {
				compatible = "snps,dwc3";
				reg = <0xf7d00000 0x20000>;
				interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
				dr_mode = "host";
			};
		};

		usb_phy1: phy@f7d20100 {
			compatible = "syna,vs680-usb3-phy";
			reg = <0xf7d20100 0x20>;
			#phy-cells = <0>;
			resets = <&chip 0x688 0 1 0>;
			reset-names = "phy";
			status = "disabled";
		};

		pcie0: pcie@f7e40000 {
			compatible = "syna,vs680-pcie";
			reg = <0xf7e40000 0x8000>, <0xf7e4a000 0x28>, <0xe0000000 0x00800000>;
			reg-names = "dbi", "ctrl", "config";
			interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
			clocks = <&gateclk CLK_PCIE0SYS>;
			resets = <&chip 0x688 1 1 0>;
			#address-cells = <3>;
			#size-cells = <2>;
			#interrupt-cells = <1>;
			interrupt-map-mask = <0 0 0 0>;
			interrupt-map = <0 0 0 0 &gic GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
			num-lanes = <2>;
			num-viewport = <4>;
			device_type = "pci";
			ranges = <0x81000000 0 0          0xe0800000 0 0x00800000
				  0x82000000 0 0xe1000000 0xe1000000 0 0x07000000>;
			phys = <&pcie_phy0>;
			phy-names = "pcie-phy";
			status = "disabled";
		};

		pcie_phy0: phy@f7e4a02c {
			compatible = "syna,vs680-pcie-phy";
			reg = <0xf7e4a02c 0x1c>;
			resets = <&chip 0x688 7 1 0>;
			#phy-cells = <0>;
			status = "disabled";
		};

		apb@f7e80000 {
			compatible = "simple-bus";
			#address-cells = <1>;
			#size-cells = <1>;
			ranges = <0 0xf7e80000 0x10000>;

			timer0: timer@0400 {
				compatible = "snps,dw-apb-timer";
				reg = <0x0400 0x14>;
				clocks = <&clk CLK_APBCORE>;
				clock-names = "timer";
				clock-freq = <200000000>;
				interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
			};

			timer1: timer@0414 {
				compatible = "snps,dw-apb-timer";
				reg = <0x0414 0x14>;
				clocks = <&clk CLK_APBCORE>;
				clock-names = "timer";
				clock-freq = <200000000>;
				status = "disabled";
			};

			timer2: timer@0428 {
				compatible = "snps,dw-apb-timer";
				reg = <0x0428 0x14>;
				clocks = <&clk CLK_APBCORE>;
				clock-names = "timer";
				clock-freq = <200000000>;
				status = "disabled";
			};

			timer3: timer@043c {
				compatible = "snps,dw-apb-timer";
				reg = <0x043c 0x14>;
				clocks = <&clk CLK_APBCORE>;
				clock-names = "timer";
				clock-freq = <200000000>;
				status = "disabled";
			};

			timer4: timer@0450 {
				compatible = "snps,dw-apb-timer";
				reg = <0x0450 0x14>;
				clocks = <&clk CLK_APBCORE>;
				clock-names = "timer";
				clock-freq = <200000000>;
				status = "disabled";
			};

			timer5: timer@0464 {
				compatible = "snps,dw-apb-timer";
				reg = <0x0464 0x14>;
				clocks = <&clk CLK_APBCORE>;
				clock-names = "timer";
				clock-freq = <200000000>;
				status = "disabled";
			};

			timer6: timer@0478 {
				compatible = "snps,dw-apb-timer";
				reg = <0x0478 0x14>;
				clocks = <&clk CLK_APBCORE>;
				clock-names = "timer";
				clock-freq = <200000000>;
				status = "disabled";
			};

			timer7: timer@048c {
				compatible = "snps,dw-apb-timer";
				reg = <0x048c 0x14>;
				clocks = <&clk CLK_APBCORE>;
				clock-names = "timer";
				clock-freq = <200000000>;
				status = "disabled";
			};

			gpio1: gpio@0800 {
				compatible = "snps,dw-apb-gpio";
				dev_name = "gpio_soc_1";
				reg = <0x0800 0x400>;
				#address-cells = <1>;
				#size-cells = <0>;

				portb: gpio-port@1 {
					gpio-controller;
					#gpio-cells = <2>;
					ngpios = <32>;
					reg = <0>;
					interrupt-controller;
					#interrupt-cells = <2>;
					#address-cells = <0>;
					interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
				};
			};

			gpio2: gpio@0c00 {
				compatible = "snps,dw-apb-gpio";
				dev_name = "gpio_soc_2";
				reg = <0x0c00 0x400>;
				#address-cells = <1>;
				#size-cells = <0>;

				portc: gpio-port@1 {
					gpio-controller;
					#gpio-cells = <2>;
					ngpios = <32>;
					reg = <0>;
					interrupt-controller;
					#interrupt-cells = <2>;
					#address-cells = <0>;
					interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
				};
			};

			uart2: uart@1000 {
				compatible = "snps,dw-apb-uart";
				reg = <0x1000 0x100>;
				interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
				clocks = <&clk CLK_APBCORE>;
				reg-shift = <2>;
				status = "disabled";
			};

			uart3: uart@1400 {
				compatible = "snps,dw-apb-uart";
				reg = <0x1400 0x100>;
				interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
				clocks = <&clk CLK_APBCORE>;
				reg-shift = <2>;
				status = "disabled";
			};

			i2c0: i2c@1800 {
				compatible = "snps,designware-i2c";
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0x1800 0x100>;
				clocks = <&clk CLK_APBCORE>;
				i2c-sda-hold-time-ns = <449>;
				i2c-sda-falling-time-ns = <425>;
				i2c-scl-falling-time-ns = <205>;
				interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
				status = "disabled";
			};

			spi1: spi@1c00 {
				compatible = "snps,dw-apb-ssi";
				reg = <0x1c00 0x100>;
				#address-cells = <1>;
				#size-cells = <0>;
				num-cs = <4>;
				clocks = <&clk CLK_APBCORE>;
				interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
				status = "disabled";
			};

			i2c1: i2c@2000 {
				compatible = "snps,designware-i2c";
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0x2000 0x100>;
				clocks = <&clk CLK_APBCORE>;
				i2c-sda-hold-time-ns = <449>;
				i2c-sda-falling-time-ns = <425>;
				i2c-scl-falling-time-ns = <205>;
				interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
				status = "disabled";
			};

			gpio0: gpio@2400 {
				compatible = "snps,dw-apb-gpio";
				dev_name = "gpio_soc_0";
				reg = <0x2400 0x400>;
				#address-cells = <1>;
				#size-cells = <0>;

				porta: gpio-port@0 {
					gpio-controller;
					#gpio-cells = <2>;
					ngpios = <32>;
					reg = <0>;
					interrupt-controller;
					#interrupt-cells = <2>;
					#address-cells = <0>;
					interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
				};
			};
		};

		chipid@f7ea0000 {
			compatible = "marvell,berlin-chipid";
			reg = <0xf7ea0000 12>;
		};

		chip: chip-control@f7ea0000 {
			compatible = "marvell,berlin4ct-chip-ctrl";
			reg = <0xf7ea0000 0x10000>;
			#reset-cells = <4>;
		};

		syspll0: syspll0 {
			compatible = "syna,vs680-pll";
			reg = <0xf7ea0200 0x20>, <0xf7ea0710 0x4>;
			#clock-cells = <1>;
			clocks = <&osc>;
			bypass-shift = /bits/ 8 <0>;
		};

		syspll1: syspll1 {
			compatible = "syna,vs680-pll";
			reg = <0xf7ea0220 0x20>, <0xf7ea0710 0x4>;
			#clock-cells = <1>;
			clocks = <&osc>;
			bypass-shift = /bits/ 8 <1>;
		};

		syspll2: syspll2 {
			compatible = "syna,vs680-pll";
			reg = <0xf7ea0240 0x20>, <0xf7ea0710 0x4>;
			#clock-cells = <1>;
			clocks = <&osc>;
			bypass-shift = /bits/ 8 <2>;
		};

		gateclk: gateclk {
			compatible = "syna,vs680-gateclk";
			reg = <0xf7ea0700 0x4>;
			#clock-cells = <1>;
		};

		clk: clk {
			compatible = "syna,vs680-clk";
			reg = <0xf7ea0720 0xf8>;
			#clock-cells = <1>;
			clocks = <&syspll0 0>, <&syspll2 0>, <&syspll0 1>, <&syspll1 1>, <&syspll2 1>, <&syspll1 0>;
		};

		pinctrl: pinctrl@f7ea8000 {
			compatible = "syna,vs680-soc-pinctrl";
			reg = <0xf7ea8000 0x10>, <0xf7ea8800 0x88>;
		};

		avio_pinctrl: pinctrl@f7ea8400 {
			compatible = "syna,vs680-avio-pinctrl";
			reg = <0xf7ea8400 0xc>, <0xf7ea8c00 0x58>;
		};

		pwm0: pwm@f7f20000 {
			compatible = "marvell,berlin-pwm";
			reg = <0xf7f20000 0x40>;
			clocks = <&clk CLK_CFG>;
			#pwm-cells = <3>;
			status = "disabled";
		};

		sm: sm@f7f80000 {
			compatible = "marvell,berlin-sm";
			reg = <0xf7f80000 0x20000>, <0xf7fe2014 4>;
			interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
			mode-bootloader = <0x29012002>;
			mode-recovery = <0x11092017>;
			mode-fastboot = <0x12510399>;
			mode-recovery,quiescent = <0x06012021>;
			mode-quiescent = <0x01112021>;
			status = "disabled";
		};

		ir: ir {
			compatible = "marvell,berlin-ir";
			status = "disabled";
		};

		apb@f7fc0000 {
			compatible = "simple-bus";
			#address-cells = <1>;
			#size-cells = <1>;
			ranges = <0 0xf7fc0000 0x10000>;
			interrupt-parent = <&sic>;

			sic: interrupt-controller@1000 {
				compatible = "snps,dw-apb-ictl";
				reg = <0x1000 0x30>;
				interrupt-controller;
				#interrupt-cells = <1>;
				#address-cells = <0>;
				interrupt-parent = <&gic>;
				interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
			};

			watchdog0: watchdog@3000 {
				compatible = "snps,dw-wdt";
				reg = <0x3000 0x100>;
				clocks = <&osc>;
				status = "disabled";
			};

			watchdog1: watchdog@4000 {
				compatible = "snps,dw-wdt";
				reg = <0x4000 0x100>;
				clocks = <&osc>;
				status = "disabled";
			};

			watchdog2: watchdog@5000 {
				compatible = "snps,dw-wdt";
				reg = <0x5000 0x100>;
				clocks = <&osc>;
				status = "disabled";
			};

			sm_gpio0: gpio@8000 {
				compatible = "snps,dw-apb-gpio";
				dev_name = "gpio_sm_0";
				reg = <0x8000 0x400>;
				#address-cells = <1>;
				#size-cells = <0>;
				no-suspend-resume;

				portd: gpio-port@4 {
					gpio-controller;
					#gpio-cells = <2>;
					ngpios = <32>;
					reg = <0>;
				};
			};

			spi0: spi@a000 {
				compatible = "snps,dw-apb-ssi";
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0xa000 0x100>;
				num-cs = <4>;
				clocks = <&osc>;
				interrupts = <5>;
				status = "disabled";
			};

			i2c2: i2c@b000 {
				compatible = "snps,designware-i2c";
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0xb000 0x100>;
				clocks = <&osc>;
				i2c-sda-hold-time-ns = <420>;
				i2c-sda-falling-time-ns = <500>;
				i2c-scl-falling-time-ns = <220>;
				interrupts = <6>;
				status = "disabled";
			};

			i2c3: i2c@c000 {
				compatible = "snps,designware-i2c";
				#address-cells = <1>;
				#size-cells = <0>;
				reg = <0xc000 0x100>;
				clocks = <&osc>;
				i2c-sda-hold-time-ns = <420>;
				i2c-sda-falling-time-ns = <500>;
				i2c-scl-falling-time-ns = <220>;
				interrupts = <7>;
				status = "disabled";
			};

			uart0: uart@d000 {
				compatible = "snps,dw-apb-uart";
				reg = <0xd000 0x100>;
				interrupts = <8>;
				clocks = <&osc>;
				reg-shift = <2>;
				status = "disabled";
			};

			uart1: uart@e000 {
				compatible = "snps,dw-apb-uart";
				reg = <0xe000 0x100>;
				interrupts = <9>;
				clocks = <&osc>;
				reg-shift = <2>;
				status = "disabled";
			};
		};

		sm_pinctrl: pinctrl@f7fe2c10 {
			compatible = "syna,vs680-system-pinctrl";
			reg = <0xf7fe2c10 0xc>, <0xf7fe2c1c 0x5c>;
		};

		isp: isp@f9100000 {
			status = "disabled";
			compatible = "syna,vs680-isp";
			reg = <0xf9100000 0x100000>;
			clocks = <&clk CLK_TXESC>, <&clk CLK_ISP>, <&clk CLK_ISSSYS>, <&clk CLK_ISPBE>,
				 <&clk CLK_ISPDSC>, <&clk CLK_ISPCSI0>, <&clk CLK_ISPCSI1>;
			clock-names = "txescclk", "ispclk", "isssysclk", "ispbeclk",
				      "ispdscclk", "ispcsi0clk", "ispcsi1clk";
			resets = <&chip 0x688 8 1 0>;
			reset-names = "isprst";
			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
				     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
			interrupt-names = "isp_core",
					  "isp_tsb_dhub";
		};

		cec: cec@f7fe1000 {
			compatible = "syna,berlin-cec";
			interrupt-parent = <&sic>;
			interrupts = <16>;
			reg = <0xf7fe1000 0x1000>;
			status = "disabled";
		};

		vpp: vpp {
			status = "disabled";
			compatible = "syna,vpp-drv";
			clocks = <&vpll0 0>, <&vpll1 0>;
			clock-names = "avio_vclk0", "avio_dpiclk";
		};

		fb: fb {
			compatible = "marvell,berlin-fb";
			frame-size-ndx = <1>;
			status = "disabled";
		};
	};
};

pinctrl-vs680.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Synaptics VS680 pinctrl driver
 *
 * Copyright (C) 2019 Synaptics Incorporated
 *
 * Author: Jisheng Zhang <jszhang@kernel.org>
 */

#include <linux/init.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#include "berlin.h"

static const struct berlin_desc_group vs680_soc_pinctrl_groups[] = {
	BERLIN_PINCTRLCONF_GROUP("SDIO_CDn", 0x0, 0x3, 0x00,
			0x0, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "sdio"), /* CDn */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* GPIO45 */
			BERLIN_PINCTRL_FUNCTION(0x2, "tw1a")), /* SCL */
	BERLIN_PINCTRLCONF_GROUP("SDIO_WP", 0x0, 0x3, 0x03,
			0x4, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "sdio"), /* WP */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* GPIO44 */
			BERLIN_PINCTRL_FUNCTION(0x2, "tw1a")), /* SDA */
	BERLIN_PINCTRLCONF_GROUP("SPI1_SS0n", 0x0, 0x3, 0x06,
			0x8, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), /* SS0n */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO54 */
	BERLIN_PINCTRLCONF_GROUP("SPI1_SS1n", 0x0, 0x3, 0x09,
			0xc, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO53 */
			BERLIN_PINCTRL_FUNCTION(0x1, "spi1"), /* SS1n */
			BERLIN_PINCTRL_FUNCTION(0x2, "sts7"), /* VALD */
			BERLIN_PINCTRL_FUNCTION(0x4, "pwm"), /* PWM1 */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG14 */
	BERLIN_PINCTRLCONF_GROUP("SPI1_SS2n", 0x0, 0x3, 0x0c,
			0x10, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO52 */
			BERLIN_PINCTRL_FUNCTION(0x1, "spi1"), /* SS2n */
			BERLIN_PINCTRL_FUNCTION(0x2, "sts7"), /* CLK */
			BERLIN_PINCTRL_FUNCTION(0x3, "tw1b"), /* SCL */
			BERLIN_PINCTRL_FUNCTION(0x4, "pwm"), /* PWM0 */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG12 */
	BERLIN_PINCTRLCONF_GROUP("SPI1_SS3n", 0x0, 0x3, 0x0f,
			0x14, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO51 */
			BERLIN_PINCTRL_FUNCTION(0x1, "spi1"), /* SS3n */
			BERLIN_PINCTRL_FUNCTION(0x2, "sts7"), /* SD */
			BERLIN_PINCTRL_FUNCTION(0x3, "tw1b"), /* SDA */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG13 */
	BERLIN_PINCTRLCONF_GROUP("SPI1_SDO", 0x0, 0x3, 0x12,
			0x18, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), /* SDO */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO50 */
	BERLIN_PINCTRLCONF_GROUP("SPI1_SCLK", 0x0, 0x3, 0x15,
			0x1c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), /* SCLK */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* GPIO49 */
			BERLIN_PINCTRL_FUNCTION(0x7, "dbg")), /* CLK */
	BERLIN_PINCTRLCONF_GROUP("SPI1_SDI", 0x0, 0x3, 0x18,
			0x20, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), /* SDI */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO48 */
	BERLIN_PINCTRLCONF_GROUP("TW0_SCL", 0x0, 0x3, 0x1b,
			0x24, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO47 */
			BERLIN_PINCTRL_FUNCTION(0x1, "tw0"), /* SCL */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG10 */
	BERLIN_PINCTRLCONF_GROUP("TW0_SDA", 0x4, 0x3, 0x00,
			0x28, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO46 */
			BERLIN_PINCTRL_FUNCTION(0x1, "tw0"), /* SDA */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG11 */
	BERLIN_PINCTRLCONF_GROUP("STS0_CLK", 0x4, 0x3, 0x03,
			0x2c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO43 */
			BERLIN_PINCTRL_FUNCTION(0x1, "sts0"), /* CLK */
			BERLIN_PINCTRL_FUNCTION(0x2, "cpupll"), /* CLKO */
			BERLIN_PINCTRL_FUNCTION(0x4, "uart3"), /* RXD */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG0 */
	BERLIN_PINCTRLCONF_GROUP("STS0_SOP", 0x4, 0x3, 0x06,
			0x30, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO42 */
			BERLIN_PINCTRL_FUNCTION(0x1, "sts0"), /* SOP */
			BERLIN_PINCTRL_FUNCTION(0x2, "syspll"), /* CLKO */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts5"), /* CLK */
			BERLIN_PINCTRL_FUNCTION(0x4, "uart3"), /* TXD */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG1 */
	BERLIN_PINCTRLCONF_GROUP("STS0_SD", 0x4, 0x3, 0x09,
			0x34, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO41 */
			BERLIN_PINCTRL_FUNCTION(0x1, "sts0"), /* SD */
			BERLIN_PINCTRL_FUNCTION(0x2, "mempll"), /* CLKO */
			BERLIN_PINCTRL_FUNCTION(0x4, "uart3"), /* CTSn */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG2 */
	BERLIN_PINCTRLCONF_GROUP("STS0_VALD", 0x4, 0x3, 0x0c,
			0x38, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO40 */
			BERLIN_PINCTRL_FUNCTION(0x1, "sts0"), /* VALD */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts5"), /* SD */
			BERLIN_PINCTRL_FUNCTION(0x4, "uart3"), /* RTSn */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG3 */
	BERLIN_PINCTRLCONF_GROUP("STS1_CLK", 0x4, 0x3, 0x0f,
			0x3c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO39 */
			BERLIN_PINCTRL_FUNCTION(0x1, "sts1"), /* CLK */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm"), /* pwm0 */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG4 */
	BERLIN_PINCTRLCONF_GROUP("STS1_SOP", 0x4, 0x3, 0x12,
			0x40, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO38 */
			BERLIN_PINCTRL_FUNCTION(0x1, "sts1"), /* SOP */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm"), /* PWM1 */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts6"), /* CLK */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG5 */
	BERLIN_PINCTRLCONF_GROUP("STS1_SD", 0x4, 0x3, 0x15,
			0x44, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO37 */
			BERLIN_PINCTRL_FUNCTION(0x1, "sts1"), /* SD */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm"), /* PWM2 */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG6 */
	BERLIN_PINCTRLCONF_GROUP("STS1_VALD", 0x4, 0x3, 0x18,
			0x48, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO36 */
			BERLIN_PINCTRL_FUNCTION(0x1, "sts1"), /* VALD */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm"), /* PWM3 */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts6"), /* SD */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG7 */
	BERLIN_PINCTRLCONF_GROUP("USB2_DRV_VBUS", 0x4, 0x3, 0x1b,
			0x4c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "usb2"), /* VBUS */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO55 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_MDC", 0x8, 0x3, 0x00,
			0x50, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* MDC */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* GPIO29 */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG8 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_MDIO", 0x8, 0x3, 0x03,
			0x54, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* MDIO */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* GPIO28 */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG9 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_TXC", 0x8, 0x3, 0x06,
			0x58, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* TXC */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO23 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_TXD0", 0x8, 0x3, 0x09,
			0x5c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* TXD0 */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO27 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_TXD1", 0x8, 0x3, 0x0c,
			0x60, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* TXD1 */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* GPIO26 */
			BERLIN_PINCTRL_FUNCTION(0x7, "phy")), /* DBG15 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_TXD2", 0x8, 0x3, 0x0f,
			0x64, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* TXD2 */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO25 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_TXD3", 0x8, 0x3, 0x12,
			0x68, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* TXD3 */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO24 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_TXCTL", 0x8, 0x3, 0x15,
			0x6c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* TXCTL */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO22 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_RXC", 0x8, 0x3, 0x18,
			0x70, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* RXC */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO31 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_RXD0", 0x8, 0x3, 0x1b,
			0x74, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* RXD0 */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO35 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_RXD1", 0xc, 0x3, 0x00,
			0x78, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* RXD1 */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO34 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_RXD2", 0xc, 0x3, 0x03,
			0x7c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* RXD2 */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO33 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_RXD3", 0xc, 0x3, 0x06,
			0x80, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* RXD3 */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO32 */
	BERLIN_PINCTRLCONF_GROUP("RGMII_RXCTL", 0xc, 0x3, 0x09,
			0x84, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rgmii"), /* RXCTL */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* GPIO30 */
};

static const struct berlin_desc_group vs680_avio_pinctrl_groups[] = {
	BERLIN_PINCTRLCONF_GROUP("I2S1_DO0", 0x0, 0x3, 0x00,
			0x0, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO19 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"), /* DO0 */
			BERLIN_PINCTRL_FUNCTION(0x7, "avio")), /* DBG4 */
	BERLIN_PINCTRLCONF_GROUP("I2S1_DO1", 0x0, 0x3, 0x03,
			0x4, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO17 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"), /* DO1 */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts2"), /* CLK */
			BERLIN_PINCTRL_FUNCTION(0x7, "avio")), /* DBG5 */
	BERLIN_PINCTRLCONF_GROUP("I2S1_DO2", 0x0, 0x3, 0x06,
			0x8, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO16 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"), /* DO2 */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm"), /* PWM2 */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts2"), /* SD */
			BERLIN_PINCTRL_FUNCTION(0x4, "pdm"), /* DI2 */
			BERLIN_PINCTRL_FUNCTION(0x7, "avio")), /* DBG6 */
	BERLIN_PINCTRLCONF_GROUP("I2S1_DO3", 0x0, 0x3, 0x09,
			0xc, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO15 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"), /* DO3 */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm"), /* PWM3 */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts3"), /* CLK */
			BERLIN_PINCTRL_FUNCTION(0x4, "pdm"), /* DI3 */
			BERLIN_PINCTRL_FUNCTION(0x7, "avio")), /* DBG7 */
	BERLIN_PINCTRLCONF_GROUP("I2S1_LRCKIO", 0x0, 0x3, 0x0c,
			0x10, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO21 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"), /* LRCKIO */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm"), /* PWM0 */
			BERLIN_PINCTRL_FUNCTION(0x3, "arc_test"), /* OUT */
			BERLIN_PINCTRL_FUNCTION(0x7, "avio")), /* DBG0 */
	BERLIN_PINCTRLCONF_GROUP("I2S1_BCLKIO", 0x0, 0x3, 0x0f,
			0x14, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO20 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"), /* BCLKIO */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm"), /* PWM1 */
			BERLIN_PINCTRL_FUNCTION(0x7, "avio")), /* DBG1 */
	BERLIN_PINCTRLCONF_GROUP("SPDIFO", 0x0, 0x3, 0x12,
			0x18, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO14 */
			BERLIN_PINCTRL_FUNCTION(0x1, "spdifo"),
			BERLIN_PINCTRL_FUNCTION(0x4, "avpll")), /* CLKO */
	BERLIN_PINCTRLCONF_GROUP("SPDIFI", 0x0, 0x3, 0x15,
			0x1c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO4 */
			BERLIN_PINCTRL_FUNCTION(0x1, "spdifi"),
			BERLIN_PINCTRL_FUNCTION(0x2, "pdm")), /* DI */
	BERLIN_PINCTRLCONF_GROUP("I2S2_LRCKIO", 0x0, 0x3, 0x18,
			0x20, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO13 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s2")), /* LRCKIO */
	BERLIN_PINCTRLCONF_GROUP("I2S2_BCLKIO", 0x0, 0x3, 0x1b,
			0x24, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO12 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"), /* BCLKIO */
			BERLIN_PINCTRL_FUNCTION(0x2, "pdm")), /* CLKIO */
	BERLIN_PINCTRLCONF_GROUP("I2S2_DI0", 0x4, 0x3, 0x00,
			0x28, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO11 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"), /* DI0 */
			BERLIN_PINCTRL_FUNCTION(0x2, "pdm")), /* DI3 */
	BERLIN_PINCTRLCONF_GROUP("I2S2_DI1", 0x4, 0x3, 0x03,
			0x2c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO10 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"), /* DI1 */
			BERLIN_PINCTRL_FUNCTION(0x2, "pdm"), /* DI2 */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts3")), /* SD */
	BERLIN_PINCTRLCONF_GROUP("I2S2_DI2", 0x4, 0x3, 0x06,
			0x30, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO9 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"), /* DI2 */
			BERLIN_PINCTRL_FUNCTION(0x2, "pdm"), /* DI1 */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts4")), /* CLK */
	BERLIN_PINCTRLCONF_GROUP("I2S2_DI3", 0x4, 0x3, 0x09,
			0x34, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO8 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"), /* DI3 */
			BERLIN_PINCTRL_FUNCTION(0x2, "pdm"), /* DI0 */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts4")), /* SD */
	BERLIN_PINCTRLCONF_GROUP("I2S1_MCLK", 0x4, 0x3, 0x0c,
			0x38, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO18 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"), /* MCLK */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts2"), /* SOP */
			BERLIN_PINCTRL_FUNCTION(0x7, "avio")), /* DBG3 */
	BERLIN_PINCTRLCONF_GROUP("I2S2_MCLK", 0x4, 0x3, 0x0f,
			0x3c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO7 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"), /* MCLK */
			BERLIN_PINCTRL_FUNCTION(0x2, "pdm"), /* CLKIO */
			BERLIN_PINCTRL_FUNCTION(0x4, "hdmi")), /* FBCLK */
	BERLIN_PINCTRLCONF_GROUP("TX_EDDC_SCL", 0x4, 0x3, 0x12,
			0x40, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO6 */
			BERLIN_PINCTRL_FUNCTION(0x1, "tx_eddc")), /* SCL */
	BERLIN_PINCTRLCONF_GROUP("TX_EDDC_SDA", 0x4, 0x3, 0x15,
			0x44, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO5 */
			BERLIN_PINCTRL_FUNCTION(0x1, "tx_eddc")), /* SDA */
	BERLIN_PINCTRLCONF_GROUP("I2S3_DO", 0x4, 0x3, 0x18,
			0x48, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO1 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s3"), /* DO */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts3"), /* SOP */
			BERLIN_PINCTRL_FUNCTION(0x7, "avio")), /* DBG2 */
	BERLIN_PINCTRLCONF_GROUP("I2S3_LRCKIO", 0x4, 0x3, 0x1b,
			0x4c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO3 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s3"), /* LRCKIO */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts3")), /* CLK */
	BERLIN_PINCTRLCONF_GROUP("I2S3_BCLKIO", 0x8, 0x3, 0x00,
			0x50, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO2 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s3"), /* BCLKIO */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts3")), /* SD */
	BERLIN_PINCTRLCONF_GROUP("I2S3_DI", 0x8, 0x3, 0x03,
			0x54, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO0 */
			BERLIN_PINCTRL_FUNCTION(0x1, "i2s3"), /* DI */
			BERLIN_PINCTRL_FUNCTION(0x3, "sts3")), /* VALD */
};

static const struct berlin_desc_group vs680_sysmgr_pinctrl_groups[] = {
	BERLIN_PINCTRLCONF_GROUP("SM_TW2_SCL", 0x0, 0x3, 0x00,
			0x0, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rx_edid"), /* SCL */
			BERLIN_PINCTRL_FUNCTION(0x1, "tw2a"), /* SCL */
			BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), /* SM GPIO0 */
	BERLIN_PINCTRLCONF_GROUP("SM_TW2_SDA", 0x0, 0x3, 0x03,
			0x4, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "rx_edid"), /* SDA */
			BERLIN_PINCTRL_FUNCTION(0x1, "tw2a"), /* SDA */
			BERLIN_PINCTRL_FUNCTION(0x2, "gpio")), /* SM GPIO1 */
	BERLIN_PINCTRLCONF_GROUP("SM_URT1_TXD", 0x0, 0x3, 0x06,
			0x8, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "porb"), /* VOUT 1p05 */
			BERLIN_PINCTRL_FUNCTION(0x1, "uart1"), /* TXD */
			BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), /* SM GPIO4 */
			BERLIN_PINCTRL_FUNCTION(0x3, "pwm"), /* PWM2 */
			BERLIN_PINCTRL_FUNCTION(0x4, "timer"), /* TIMER0 */
			BERLIN_PINCTRL_FUNCTION(0x5, "porb"), /* AVDD LV */
			BERLIN_PINCTRL_FUNCTION(0x6, "tw2b")), /* SCL */
	BERLIN_PINCTRLCONF_GROUP("SM_URT1_RXD", 0x0, 0x3, 0x09,
			0xc, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* SM GPIO5 */
			BERLIN_PINCTRL_FUNCTION(0x1, "uart1"), /* RXD */
			BERLIN_PINCTRL_FUNCTION(0x2, "clk_25m"),
			BERLIN_PINCTRL_FUNCTION(0x3, "pwm"), /* PWM3 */
			BERLIN_PINCTRL_FUNCTION(0x4, "timer"), /* TIMER1 */
			BERLIN_PINCTRL_FUNCTION(0x5, "por"), /* VDDSOC_RSTB */
			BERLIN_PINCTRL_FUNCTION(0x6, "tw2b")), /* SDA */
	BERLIN_PINCTRLCONF_GROUP("SM_HDMI_HPD", 0x0, 0x3, 0x0c,
			0x10, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* SM GPIO2 */
			BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")), /* HPD */
	BERLIN_PINCTRLCONF_GROUP("SM_HDMI_CEC", 0x0, 0x3, 0x0f,
			0x14, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* SM GPIO3 */
			BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")), /* CEC */
	BERLIN_PINCTRLCONF_GROUP("SM_TMS", 0x0, 0x3, 0x12,
			0x18, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "jtag"), /* TMS */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* SM GPIO6 */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm")), /* PWM0 */
	BERLIN_PINCTRLCONF_GROUP("SM_TDI", 0x0, 0x3, 0x15,
			0x1c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "jtag"), /* TDI */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* SM GPIO7 */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm")), /* PWM1 */
	BERLIN_PINCTRLCONF_GROUP("SM_TDO", 0x0, 0x3, 0x18,
			0x20, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "jtag"), /* TDO */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* SM GPIO8 */
	BERLIN_PINCTRLCONF_GROUP("SM_TW3_SCL", 0x0, 0x3, 0x1b,
			0x24, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* SM GPIO9 */
			BERLIN_PINCTRL_FUNCTION(0x1, "tw3"), /* SCL */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm")), /* PWM2 */
	BERLIN_PINCTRLCONF_GROUP("SM_TW3_SDA", 0x4, 0x3, 0x00,
			0x28, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* SM GPIO10 */
			BERLIN_PINCTRL_FUNCTION(0x1, "tw3"), /* SDA */
			BERLIN_PINCTRL_FUNCTION(0x2, "pwm")), /* PWM3 */
	BERLIN_PINCTRLCONF_GROUP("SM_SPI2_SS0n", 0x4, 0x3, 0x03,
			0x2c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "spi2"), /* SS0 n*/
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* SM GPIO17 */
			BERLIN_PINCTRL_FUNCTION(0x7, "porb")), /* AVDD33_LV */
	BERLIN_PINCTRLCONF_GROUP("SM_SPI2_SS1n", 0x4, 0x3, 0x06,
			0x30, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* SM GPIO16 */
			BERLIN_PINCTRL_FUNCTION(0x1, "spi2"), /* SS1n */
			BERLIN_PINCTRL_FUNCTION(0x6, "uart1"), /* RTSn */
			BERLIN_PINCTRL_FUNCTION(0x7, "vdd")), /* CPU PORTB */
	BERLIN_PINCTRLCONF_GROUP("SM_SPI2_SS2n", 0x4, 0x3, 0x09,
			0x34, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "mon"), /* VDD 1P8 */
			BERLIN_PINCTRL_FUNCTION(0x1, "spi2"), /* SS2n */
			BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), /* SM GPIO15 */
			BERLIN_PINCTRL_FUNCTION(0x3, "pwm"), /* PWM0 */
			BERLIN_PINCTRL_FUNCTION(0x4, "timer"), /* TIMER0 */
			BERLIN_PINCTRL_FUNCTION(0x5, "uart2"), /* TXD */
			BERLIN_PINCTRL_FUNCTION(0x7, "clk_25m")),
	BERLIN_PINCTRLCONF_GROUP("SM_SPI2_SS3n", 0x4, 0x3, 0x0c,
			0x38, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "pwr_ok"),
			BERLIN_PINCTRL_FUNCTION(0x1, "spi2"), /* SS3n */
			BERLIN_PINCTRL_FUNCTION(0x2, "gpio"), /* SM GPIO14 */
			BERLIN_PINCTRL_FUNCTION(0x3, "pwm"), /* PWM1 */
			BERLIN_PINCTRL_FUNCTION(0x4, "timer"), /* TIMER1 */
			BERLIN_PINCTRL_FUNCTION(0x5, "uart2"), /* RXD */
			BERLIN_PINCTRL_FUNCTION(0x7, "uart1")), /* CTSn */
	BERLIN_PINCTRLCONF_GROUP("SM_SPI2_SDO", 0x4, 0x3, 0x0f,
			0x3c, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "spi2"), /* SDO */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* SM GPIO13 */
			BERLIN_PINCTRL_FUNCTION(0x2, "uart2")), /* RTSn */
	BERLIN_PINCTRLCONF_GROUP("SM_SPI2_SDI", 0x4, 0x3, 0x12,
			0x40, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "spi2"), /* SDI */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* SM GPIO12 */
			BERLIN_PINCTRL_FUNCTION(0x2, "uart2")), /* CTSn */
	BERLIN_PINCTRLCONF_GROUP("SM_SPI2_SCLK", 0x4, 0x3, 0x15,
			0x44, 0x3, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "spi2"), /* SCLK */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* SM GPIO11 */
	BERLIN_PINCTRLCONF_GROUP("SM_URT0_TXD", 0x4, 0x3, 0x18,
			0x48, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* TXD */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* SM GPIO19 */
	BERLIN_PINCTRLCONF_GROUP("SM_URT0_RXD", 0x4, 0x3, 0x1b,
			0x4c, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* RXD */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* SM GPIO18 */
	BERLIN_PINCTRLCONF_GROUP("SM_HDMIRX_HPD", 0x8, 0x3, 0x00,
			0x50, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "hdmirx"), /* HPD */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* SM GPIO20 */
	BERLIN_PINCTRLCONF_GROUP("SM_HDMIRX_PWR5V", 0x8, 0x3, 0x03,
			0x54, 0x4, 0x0,
			BERLIN_PINCTRL_FUNCTION(0x0, "hdmirx"), /* PWR5V */
			BERLIN_PINCTRL_FUNCTION(0x1, "gpio")), /* SM GPIO21 */
};

static const struct berlin_pinctrl_desc vs680_soc_pinctrl_data = {
	.groups = vs680_soc_pinctrl_groups,
	.ngroups = ARRAY_SIZE(vs680_soc_pinctrl_groups),
};

static const struct berlin_pinctrl_desc vs680_avio_pinctrl_data = {
	.groups = vs680_avio_pinctrl_groups,
	.ngroups = ARRAY_SIZE(vs680_avio_pinctrl_groups),
};

static const struct berlin_pinctrl_desc vs680_sysmgr_pinctrl_data = {
	.groups = vs680_sysmgr_pinctrl_groups,
	.ngroups = ARRAY_SIZE(vs680_sysmgr_pinctrl_groups),
};

static const struct of_device_id vs680_pinctrl_match[] = {
	{
		.compatible = "syna,vs680-soc-pinctrl",
		.data = &vs680_soc_pinctrl_data,
	},
	{
		.compatible = "syna,vs680-avio-pinctrl",
		.data = &vs680_avio_pinctrl_data,
	},
	{
		.compatible = "syna,vs680-system-pinctrl",
		.data = &vs680_sysmgr_pinctrl_data,
	},
	{}
};

static int vs680_pinctrl_probe(struct platform_device *pdev)
{
	const struct of_device_id *match =
		of_match_device(vs680_pinctrl_match, &pdev->dev);
	struct regmap_config *rmconfig;
	struct regmap *regmap, *conf;
	struct resource *res;
	void __iomem *base;

	rmconfig = devm_kzalloc(&pdev->dev, sizeof(*rmconfig), GFP_KERNEL);
	if (!rmconfig)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	rmconfig->reg_bits = 32,
	rmconfig->val_bits = 32,
	rmconfig->reg_stride = 4,
	rmconfig->max_register = resource_size(res);

	regmap = devm_regmap_init_mmio(&pdev->dev, base, rmconfig);
	if (IS_ERR(regmap))
		return PTR_ERR(regmap);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	rmconfig->name = "conf";
	rmconfig->max_register = resource_size(res);

	conf = devm_regmap_init_mmio(&pdev->dev, base, rmconfig);
	if (IS_ERR(conf))
		return PTR_ERR(conf);

	return berlin_pinctrl_probe_regmap(pdev, match->data, regmap, conf);
}

static const struct dev_pm_ops vs680_pinctrl_pm_ops = {
	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(berlin_pinctrl_suspend, berlin_pinctrl_resume)
};

static struct platform_driver vs680_pinctrl_driver = {
	.probe	= vs680_pinctrl_probe,
	.driver	= {
		.name = "vs680-pinctrl",
		.pm = &vs680_pinctrl_pm_ops,
		.of_match_table = vs680_pinctrl_match,
	},
};

static int __init vs680_pinctrl_init(void)
{
	return platform_driver_register(&vs680_pinctrl_driver);
}
arch_initcall(vs680_pinctrl_init);

内核对设备树的处理

在这里插入图片描述
1.dts被编译为dtb文件
2.u-boot把dtb文件传给内核
3.内核解析dtb文件,把每一个节点都转换为device_node结构体
4.对于某些device_node结构体,会被转换为platform_device结构体

Q:哪些设备树节点会被转换为platform_device
1.根节点下含有compatible属性的子节点
2.总线I2C,SPI节点下的子节点:不转换为platform_device

匹配过程

linux内核中,设备驱动程序与设备节点的匹配是通过以下步骤来完成的:

1.设备树解析

在启动过程中,bootloader负责将设备树(通常是一个编译后的.dtb文件)传递给内核。内核会为每个设备树节点创建对应的设备对象,这些对象通常是device结构体及其子类(如platform_device)的实例。
device 结构体:
通用设备结构体,包含设备的基本属性和状态信息。

struct device {
    struct device *parent;
    struct device_private *p;
    struct kobject kobj;
    const char *init_name; /* initial name of the device */
    const struct device_type *type;
    struct mutex mutex;    /* mutex to synchronize calls to its driver. */
    struct bus_type *bus;  /* type of bus device is on */
    struct device_driver *driver; /* which driver has allocated this */
    void *platform_data;   /* Platform specific data, device core doesn't touch it */
    struct dev_pm_info power;
    ...
};

platform_device 结构体:
代表具体的设备,包含设备资源和设备节点信息。

struct platform_device {
    const char *name;
    int id;
    struct device dev;
    u32 num_resources;
    struct resource *resource;
    ...
};

以及device_node 结构体和resource 结构体等等。

2.平台驱动定义和注册

2.1平台驱动程序的定义

首先,定义了一个 platform_driver 结构体,创建一个vs680_pinctrl_driver对象,描述了这个驱动程序的基本信息和操作函数:
在这里插入图片描述

2.2 驱动的注册

在内核初始化时,会调用 vs680_pinctrl_init 函数注册这个驱动(vs680_pinctrl_driver)
在这里插入图片描述
vs680_pinctrl_init 函数调用 platform_driver_registervs680_pinctrl_driver 注册到内核中。

arch_initcall 宏确保 vs680_pinctrl_init 函数在内核架构初始化阶段被调用。

3.设备与驱动匹配

  • 设备树中的每个设备节点都有一个或多个 compatible 属性,用于描述设备的类型和兼容性信息。
  • 驱动程序中会定义一个 of_device_id 结构体数组,数组的每个条目描述了一个可能的设备匹配规则,包括设备的 compatible 属性值。
  • 当内核在设备树中找到一个设备节点时,它会遍历驱动程序的 of_device_id 数组,尝试将设备节点的 compatible 属性与数组条目中的值进行匹配。
    static const struct of_device_id vs680_pinctrl_match叫做驱动程序的匹配表。
    在这里插入图片描述
    在vs680-a0.dtsi中会有
    在这里插入图片描述

在这里插入图片描述

vs680_pinctrl_match作为参数传递到平台驱动的of_match_table在这里插入图片描述

4.驱动程序探测函数probe

当找到匹配的compatible属性时,内核会调用驱动程序相关的初始化函数probe。
vs680_pinctrl_probe 函数中,使用 of_match_device 函数查找与当前设备节点(pdev->dev)匹配的项。如果找到匹配项,match->data 就会指向 vs680_soc_pinctrl_data。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
首先,我们定义了 berlin_pinctrl_desc 结构体对象,用于描述特定 SoC 的引脚控制器配置信息:
berlin_pinctrl_desc 是一个包含引脚组描述的结构体,用于定义特定 SoC 引脚控制器的配置信息。它在匹配设备树节点后,在探测函数 (vs680_pinctrl_probe) 中被使用,通过 match->data 传递给引脚控制子系统的初始化函数berlin_pinctrl_probe_regmap
在这里插入图片描述

然后,在设备树匹配表 vs680_pinctrl_match 中,将这个 berlin_pinctrl_desc 结构体对象与特定的设备树节点进行关联,并在 vs680_pinctrl_probe 函数中,通过 of_match_device 函数查找匹配项,并获取 berlin_pinctrl_desc 结构体对象vs680_soc_pinctrl_data
在这里插入图片描述
此时match->data 包含了针脚控制描述符的数据(如 vs680_soc_pinctrl_data),用于后续的初始化。
在这里插入图片描述

在这里插入图片描述
vs680_soc_pinctrl_groups描述了各个引脚的功能选择
以uart3为例,
.dts或.dtsi会有
在这里插入图片描述

uart3的一个group是STS0_CLK
那么在pinctrl.c中会有对应的描述
在这里插入图片描述
如果想换成普通gpio,那么改成function = "gpio";
一般在芯片公司提供的引脚描述表pin_mux中也能找到相应的描述(搜索group关键词STS0_CLK)
在这里插入图片描述

probe中设备资源初始化

在 Linux 内核开发中,特别是在处理设备驱动程序时,使用了一些函数来获取设备资源并进行必要的初始化。
流程:在 vs680_pinctrl_probe 函数中,先通过 platform_get_resource 获取设备的内存资源,然后通过 devm_ioremap_resource 将资源映射到内核地址空间,最后使用 devm_regmap_init_mmio 初始化寄存器映射配置,准备后续的寄存器访问操作。
1. platform_get_resource
platform_get_resource 函数用于获取设备的资源,例如内存区域、IO 端口等。它的原型定义如下:

struct resource *platform_get_resource(struct platform_device *pdev,
                                       unsigned int type, unsigned int num);
  • pdev: 指向 platform_device 结构体的指针,代表当前的平台设备。
  • type: 资源类型,可以是 IORESOURCE_MEM(内存区域)或者 IORESOURCE_IRQ(中断资源)等。
  • num: 资源编号,对于同一类型的资源可能会有多个,通过 num 来指定具体的资源。

匹配关系:
platform_get_resource 通过传入的 pdev 参数来获取与当前平台设备相关联的资源信息。
在 vs680_pinctrl_probe 函数中,首先通过调用 platform_get_resource(pdev, IORESOURCE_MEM, 0)platform_get_resource(pdev, IORESOURCE_MEM, 1) 分别获取两个内存资源区域。
2. devm_ioremap_resource
devm_ioremap_resource 函数用于将获取到的设备资源进行内存映射,返回一个指向映射后地址空间的指针。其原型定义如下:

void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
  • dev: 设备的 struct device 结构体指针,通常使用 &pdev->dev。
  • res: platform_get_resource 返回的资源结构体指针。

匹配关系:
devm_ioremap_resource 通过 pdev->dev 和由 platform_get_resource 返回的资源结构体指针 res,来映射设备的物理地址空间到内核的虚拟地址空间。
3. devm_regmap_init_mmio
devm_regmap_init_mmio 函数用于初始化寄存器映射配置,它是在成功映射设备资源后对寄存器进行访问的重要步骤。其原型定义如下:

struct regmap *devm_regmap_init_mmio(struct device *dev,
                                     void __iomem *base,
                                     const struct regmap_config *config);
  • dev: 设备的 struct device 结构体指针,通常使用 &pdev->dev。
  • base: 映射后的寄存器基地址,通常是 devm_ioremap_resource 返回的值。
  • config: struct regmap_config 结构体指针,用于配置寄存器映射的属性,例如寄存器位宽、寄存器间距等。

匹配关系:
devm_regmap_init_mmio 在 vs680_pinctrl_probe 函数中被调用,传入了 pdev->dev、通过 devm_ioremap_resource 映射后的基地址 base,以及之前配置好的 rmconfig 结构体指针。
这个函数返回一个 struct regmap 结构体指针,表示成功初始化的寄存器映射对象,可以用于后续的寄存器访问操作。

在这里插入图片描述

  • 26
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值