// SPDX-License-Identifier: BSD-3-Clause
/*
 * Copyright (c) 2021, Luca Weiss <luca@z3ntu.xyz>
 */

/dts-v1/;

/* PM7250B is configured to use SID2/3 */
#define PM7250B_SID 2
#define PM7250B_SID1 3

/* PMK8350 (in reality a PMK8003) is configured to use SID6 instead of 0 */
#define PMK8350_SID 6

#include <dt-bindings/firmware/qcom,scm.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include "sm7225.dtsi"
#include "pm6150l.dtsi"
#include "pm6350.dtsi"
#include "pm7250b.dtsi"
#include "pmk8350.dtsi"

/ {
	model = "Fairphone 4";
	compatible = "fairphone,fp4", "qcom,sm7225";
	chassis-type = "handset";

	/* required for bootloader to select correct board */
	qcom,msm-id = <434 0x10000>, <459 0x10000>;
	qcom,board-id = <8 32>;

	aliases {
		serial0 = &uart9;
		serial1 = &uart1;
	};

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

		stdout-path = "serial0:115200n8";

		framebuffer0: framebuffer@a000000 {
			compatible = "simple-framebuffer";
			reg = <0 0xa0000000 0 (2340 * 1080 * 4)>;
			width = <1080>;
			height = <2340>;
			stride = <(1080 * 4)>;
			format = "a8r8g8b8";
		};
	};

	gpio-keys {
		compatible = "gpio-keys";
		pinctrl-names = "default";
		pinctrl-0 = <&gpio_keys_pin>;

		key-volume-up {
			label = "volume_up";
			linux,code = <KEY_VOLUMEUP>;
			gpios = <&pm6350_gpios 2 GPIO_ACTIVE_LOW>;
		};
	};

	/* Dummy regulator until PM6150L has LCDB VSP/VSN support */
	lcdb_dummy: regulator-lcdb-dummy {
		compatible = "regulator-fixed";
		regulator-name = "lcdb_dummy";
		regulator-min-microvolt = <5500000>;
		regulator-max-microvolt = <5500000>;
	};

	reserved-memory {
		/*
		 * The rmtfs memory region in downstream is 'dynamically allocated'
		 * but given the same address every time. Hard code it as this address is
		 * where the modem firmware expects it to be.
		 */
		memory@efe01000 {
			compatible = "qcom,rmtfs-mem";
			reg = <0 0xefe01000 0 0x600000>;
			no-map;

			qcom,client-id = <1>;
			qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
		};
	};

	thermal-zones {
		chg-skin-thermal {
			polling-delay-passive = <0>;
			polling-delay = <0>;
			thermal-sensors = <&pm7250b_adc_tm 0>;

			trips {
				active-config0 {
					temperature = <125000>;
					hysteresis = <1000>;
					type = "passive";
				};
			};
		};

		conn-thermal {
			polling-delay-passive = <0>;
			polling-delay = <0>;
			thermal-sensors = <&pm7250b_adc_tm 1>;

			trips {
				active-config0 {
					temperature = <125000>;
					hysteresis = <1000>;
					type = "passive";
				};
			};
		};
	};
};

&adsp {
	firmware-name = "qcom/sm7225/fairphone4/adsp.mbn";
	status = "okay";
};

&apps_rsc {
	regulators-0 {
		compatible = "qcom,pm6350-rpmh-regulators";
		qcom,pmic-id = "a";

		vreg_s1a: smps1 {
			regulator-min-microvolt = <1000000>;
			regulator-max-microvolt = <1200000>;
		};

		vreg_s2a: smps2 {
			regulator-min-microvolt = <1503000>;
			regulator-max-microvolt = <2048000>;
		};

		vreg_l2a: ldo2 {
			regulator-min-microvolt = <1503000>;
			regulator-max-microvolt = <1980000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l3a: ldo3 {
			regulator-min-microvolt = <2700000>;
			regulator-max-microvolt = <3300000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l4a: ldo4 {
			regulator-min-microvolt = <352000>;
			regulator-max-microvolt = <801000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l5a: ldo5 {
			regulator-min-microvolt = <1503000>;
			regulator-max-microvolt = <1980000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l6a: ldo6 {
			regulator-min-microvolt = <1710000>;
			regulator-max-microvolt = <3544000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l7a: ldo7 {
			regulator-min-microvolt = <1620000>;
			regulator-max-microvolt = <1980000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l8a: ldo8 {
			regulator-min-microvolt = <2800000>;
			regulator-max-microvolt = <2800000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l9a: ldo9 {
			regulator-min-microvolt = <1650000>;
			regulator-max-microvolt = <3401000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l11a: ldo11 {
			regulator-min-microvolt = <1800000>;
			regulator-max-microvolt = <2000000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l12a: ldo12 {
			regulator-min-microvolt = <1620000>;
			regulator-max-microvolt = <1980000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l13a: ldo13 {
			regulator-min-microvolt = <570000>;
			regulator-max-microvolt = <650000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l14a: ldo14 {
			regulator-min-microvolt = <1700000>;
			regulator-max-microvolt = <1900000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l15a: ldo15 {
			regulator-min-microvolt = <1100000>;
			regulator-max-microvolt = <1305000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l16a: ldo16 {
			regulator-min-microvolt = <830000>;
			regulator-max-microvolt = <921000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l18a: ldo18 {
			regulator-min-microvolt = <788000>;
			regulator-max-microvolt = <1049000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l19a: ldo19 {
			regulator-min-microvolt = <1080000>;
			regulator-max-microvolt = <1305000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l20a: ldo20 {
			regulator-min-microvolt = <530000>;
			regulator-max-microvolt = <801000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l21a: ldo21 {
			regulator-min-microvolt = <751000>;
			regulator-max-microvolt = <825000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l22a: ldo22 {
			regulator-min-microvolt = <1080000>;
			regulator-max-microvolt = <1305000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};
	};

	regulators-1 {
		compatible = "qcom,pm6150l-rpmh-regulators";
		qcom,pmic-id = "e";

		vreg_s8e: smps8 {
			regulator-min-microvolt = <313000>;
			regulator-max-microvolt = <1395000>;
		};

		vreg_l1e: ldo1 {
			regulator-min-microvolt = <1620000>;
			regulator-max-microvolt = <1980000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l2e: ldo2 {
			regulator-min-microvolt = <1170000>;
			regulator-max-microvolt = <1305000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l3e: ldo3 {
			regulator-min-microvolt = <1100000>;
			regulator-max-microvolt = <1299000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l4e: ldo4 {
			regulator-min-microvolt = <1620000>;
			regulator-max-microvolt = <3300000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l5e: ldo5 {
			regulator-min-microvolt = <1620000>;
			regulator-max-microvolt = <3300000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l6e: ldo6 {
			regulator-min-microvolt = <1700000>;
			regulator-max-microvolt = <2950000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
			regulator-allow-set-load;
			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
						   RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l7e: ldo7 {
			regulator-min-microvolt = <2700000>;
			regulator-max-microvolt = <3544000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l8e: ldo8 {
			regulator-min-microvolt = <1620000>;
			regulator-max-microvolt = <2000000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l9e: ldo9 {
			regulator-min-microvolt = <2700000>;
			regulator-max-microvolt = <2960000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
			regulator-allow-set-load;
			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
						   RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l10e: ldo10 {
			regulator-min-microvolt = <3000000>;
			regulator-max-microvolt = <3401000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_l11e: ldo11 {
			regulator-min-microvolt = <3000000>;
			regulator-max-microvolt = <3401000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
		};

		vreg_bob: bob {
			regulator-min-microvolt = <1620000>;
			regulator-max-microvolt = <5492000>;
			regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
			regulator-allow-bypass;
		};
	};
};

&cci0 {
	status = "okay";
};

&cci0_i2c0 {
	/* IMX582 @ 0x1a */
};

&cci0_i2c1 {
	/* IMX582 @ 0x1a */
};

&cci1 {
	status = "okay";
};

&cci1_i2c0 {
	/* IMX576 @ 0x10 */
};

&cdsp {
	firmware-name = "qcom/sm7225/fairphone4/cdsp.mbn";
	status = "okay";
};

&gpi_dma0 {
	status = "okay";
};

&gpi_dma1 {
	status = "okay";
};

&gpu {
	status = "okay";
};

&gpu_zap_shader {
	firmware-name = "qcom/sm7225/fairphone4/a615_zap.mbn";
};

&i2c0 {
	clock-frequency = <400000>;
	status = "okay";

	/* ST21NFCD NFC @ 8 */
	/* VL53L3 ToF @ 29 */
	/* AW88264A amplifier @ 34 */
	/* AW88264A amplifier @ 35 */
};

&i2c8 {
	clock-frequency = <400000>;
	status = "okay";

	/* HX83112A touchscreen @ 48 */
};

&i2c10 {
	/* PM8008 PMIC @ 8 and 9 */
	/* PX8618 @ 26 */
	/* SMB1395 PMIC @ 34 */
	/* awinic,aw8695 @ 5a */
};

&ipa {
	qcom,gsi-loader = "self";
	memory-region = <&pil_ipa_fw_mem>;
	firmware-name = "qcom/sm7225/fairphone4/ipa_fws.mbn";
	status = "okay";
};

&mdss {
	status = "okay";
};

&mdss_dsi0 {
	vdda-supply = <&vreg_l22a>;
	status = "okay";

	panel@0 {
		compatible = "djn,9a-3r063-1102b";
		reg = <0>;

		backlight = <&pm6150l_wled>;
		reset-gpios = <&pm6150l_gpios 9 GPIO_ACTIVE_LOW>;

		vdd1-supply = <&vreg_l1e>;
		vsn-supply = <&lcdb_dummy>;
		vsp-supply = <&lcdb_dummy>;

		port {
			panel_in: endpoint {
				remote-endpoint = <&mdss_dsi0_out>;
			};
		};
	};
};

&mdss_dsi0_out {
	data-lanes = <0 1 2 3>;
	remote-endpoint = <&panel_in>;
};

&mdss_dsi0_phy {
	vdds-supply = <&vreg_l18a>;
	status = "okay";
};

&mpss {
	firmware-name = "qcom/sm7225/fairphone4/modem.mbn";
	status = "okay";
};

&pm6150l_flash {
	status = "okay";

	led-0 {
		function = LED_FUNCTION_FLASH;
		color = <LED_COLOR_ID_YELLOW>;
		led-sources = <1>;
		led-max-microamp = <180000>;
		flash-max-microamp = <1000000>;
		flash-max-timeout-us = <1280000>;
	};

	led-1 {
		function = LED_FUNCTION_FLASH;
		color = <LED_COLOR_ID_WHITE>;
		led-sources = <2>;
		led-max-microamp = <180000>;
		flash-max-microamp = <1000000>;
		flash-max-timeout-us = <1280000>;
	};
};

&pm6150l_wled {
	qcom,switching-freq = <800>;
	qcom,current-limit-microamp = <20000>;
	qcom,num-strings = <2>;

	status = "okay";
};

&pm6350_gpios {
	gpio_keys_pin: gpio-keys-state {
		pins = "gpio2";
		function = PMIC_GPIO_FUNC_NORMAL;
		bias-pull-up;
		input-enable;
		power-source = <0>;
	};
};

&pm6350_resin {
	linux,code = <KEY_VOLUMEDOWN>;
	status = "okay";
};

&pm7250b_adc {
	channel@4d {
		reg = <ADC5_AMUX_THM1_100K_PU>;
		qcom,ratiometric;
		qcom,hw-settle-time = <200>;
		qcom,pre-scaling = <1 1>;
		label = "charger_skin_therm";
	};

	channel@4f {
		reg = <ADC5_AMUX_THM3_100K_PU>;
		qcom,ratiometric;
		qcom,hw-settle-time = <200>;
		qcom,pre-scaling = <1 1>;
		label = "conn_therm";
	};
};

&pm7250b_adc_tm {
	status = "okay";

	charger-skin-therm@0 {
		reg = <0>;
		io-channels = <&pm7250b_adc ADC5_AMUX_THM1_100K_PU>;
		qcom,ratiometric;
		qcom,hw-settle-time-us = <200>;
	};

	conn-therm@1 {
		reg = <1>;
		io-channels = <&pm7250b_adc ADC5_AMUX_THM3_100K_PU>;
		qcom,ratiometric;
		qcom,hw-settle-time-us = <200>;
	};
};

&pmk8350_rtc {
	status = "okay";
};

&pmk8350_vadc {
	channel@644 {
		reg = <PMK8350_ADC7_AMUX_THM1_100K_PU>;
		qcom,ratiometric;
		qcom,hw-settle-time = <200>;
		qcom,pre-scaling = <1 1>;
		label = "xo_therm";
	};
};

&qup_uart1_cts {
	/*
	 * Configure a bias-bus-hold on CTS to lower power
	 * usage when Bluetooth is turned off. Bus hold will
	 * maintain a low power state regardless of whether
	 * the Bluetooth module drives the pin in either
	 * direction or leaves the pin fully unpowered.
	 */
	bias-bus-hold;
};

&qup_uart1_rts {
	/* We'll drive RTS, so no pull */
	drive-strength = <2>;
	bias-disable;
};

&qup_uart1_rx {
	/*
	 * Configure a pull-up on RX. This is needed to avoid
	 * garbage data when the TX pin of the Bluetooth module is
	 * in tri-state (module powered off or not driving the
	 * signal yet).
	 */
	bias-pull-up;
};

&qup_uart1_tx {
	/* We'll drive TX, so no pull */
	drive-strength = <2>;
	bias-disable;
};

&qupv3_id_0 {
	status = "okay";
};

&qupv3_id_1 {
	status = "okay";
};

&sdc2_off_state {
	sd-cd-pins {
		pins = "gpio94";
		function = "gpio";
		drive-strength = <2>;
		bias-disable;
	};
};

&sdc2_on_state {
	sd-cd-pins {
		pins = "gpio94";
		function = "gpio";
		drive-strength = <2>;
		bias-pull-up;
	};
};

&sdhc_2 {
	vmmc-supply = <&vreg_l9e>;
	vqmmc-supply = <&vreg_l6e>;

	cd-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;

	status = "okay";
};

&tlmm {
	gpio-reserved-ranges = <13 4>, <56 2>;

	qup_uart1_sleep_cts: qup-uart1-sleep-cts-state {
		pins = "gpio61";
		function = "gpio";
		/*
		 * Configure a bias-bus-hold on CTS to lower power
		 * usage when Bluetooth is turned off. Bus hold will
		 * maintain a low power state regardless of whether
		 * the Bluetooth module drives the pin in either
		 * direction or leaves the pin fully unpowered.
		 */
		bias-bus-hold;
	};

	qup_uart1_sleep_rts: qup-uart1-sleep-rts-state {
		pins = "gpio62";
		function = "gpio";
		/*
		 * Configure pull-down on RTS. As RTS is active low
		 * signal, pull it low to indicate the BT SoC that it
		 * can wakeup the system anytime from suspend state by
		 * pulling RX low (by sending wakeup bytes).
		 */
		bias-pull-down;
	};

	qup_uart1_sleep_rx: qup-uart1-sleep-rx-state {
		pins = "gpio64";
		function = "gpio";
		/*
		 * Configure a pull-up on RX. This is needed to avoid
		 * garbage data when the TX pin of the Bluetooth module
		 * is floating which may cause spurious wakeups.
		 */
		bias-pull-up;
	};

	qup_uart1_sleep_tx: qup-uart1-sleep-tx-state {
		pins = "gpio63";
		function = "gpio";
		/*
		 * Configure pull-up on TX when it isn't actively driven
		 * to prevent BT SoC from receiving garbage during sleep.
		 */
		bias-pull-up;
	};
};

&uart1 {
	/delete-property/ interrupts;
	interrupts-extended = <&intc GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>,
			      <&tlmm 64 IRQ_TYPE_EDGE_FALLING>;

	pinctrl-names = "default", "sleep";
	pinctrl-1 = <&qup_uart1_sleep_cts>, <&qup_uart1_sleep_rts>, <&qup_uart1_sleep_tx>, <&qup_uart1_sleep_rx>;

	status = "okay";

	bluetooth {
		compatible = "qcom,wcn3988-bt";

		vddio-supply = <&vreg_l11a>;
		vddxo-supply = <&vreg_l7a>;
		vddrf-supply = <&vreg_l2e>;
		vddch0-supply = <&vreg_l10e>;
		swctrl-gpios = <&tlmm 69 GPIO_ACTIVE_HIGH>;

		max-speed = <3200000>;
	};
};

&uart9 {
	status = "okay";
};

&ufs_mem_hc {
	reset-gpios = <&tlmm 156 GPIO_ACTIVE_LOW>;

	vcc-supply = <&vreg_l7e>;
	vcc-max-microamp = <800000>;
	vccq2-supply = <&vreg_l12a>;
	vccq2-max-microamp = <800000>;

	status = "okay";
};

&ufs_mem_phy {
	vdda-phy-supply = <&vreg_l18a>;
	vdda-pll-supply = <&vreg_l22a>;

	status = "okay";
};

&usb_1 {
	status = "okay";
};

&usb_1_dwc3 {
	maximum-speed = "super-speed";
	dr_mode = "peripheral";
};

&usb_1_hsphy {
	vdd-supply = <&vreg_l18a>;
	vdda-pll-supply = <&vreg_l2a>;
	vdda-phy-dpdm-supply = <&vreg_l3a>;

	status = "okay";
};

&usb_1_qmpphy {
	vdda-phy-supply = <&vreg_l22a>;
	vdda-pll-supply = <&vreg_l16a>;

	status = "okay";
};

&wifi {
	vdd-0.8-cx-mx-supply = <&vreg_l4a>;
	vdd-1.8-xo-supply = <&vreg_l7a>;
	vdd-1.3-rfa-supply = <&vreg_l2e>;
	vdd-3.3-ch0-supply = <&vreg_l10e>;
	vdd-3.3-ch1-supply = <&vreg_l11e>;

	status = "okay";
};
