From bb3ead642d0ce80bd42df6eb565aea9da4e86652 Mon Sep 17 00:00:00 2001 From: adamg Date: Thu, 26 Oct 2023 15:58:39 +0100 Subject: [PATCH] Amlogic/linux: reorganise S922X patches for easier maintenance --- ...tch => 001.01-device-trees-to-build.patch} | 11 +- ...1.02-Add-ODROID-GO-Ultra-device-tree.patch | 1025 ++++ ...Add-Powkiddy-RGB10-MAX-3-device-tree.patch | 999 ++++ ...h => 002.01-Add-Mali-GPU-r44-driver.patch} | 0 .../002.02-Add-Mali-to-device-trees.patch | 40 + .../003.01-ODROID-N2-heartbeat-quirk.patch | 11 + .../003.02-DRM-panel-orientation-quirk.patch | 12 + ...004.01-ODROID-GO-Ultra-joypad-driver.patch | 1028 ++++ ....02-ODROID-GO-Ultra-power-off-driver.patch | 210 + .../004.03-polled-input-device-driver.patch | 402 ++ ...atch => 004.04-rk818-charger-driver.patch} | 4124 +---------------- ...i-driver.patch => 004.05-dsi-driver.patch} | 6 +- .../004.06-digital-volume-is-limited-to.patch | 17 + ...1-add-uart-ao-b-pins-to-device-trees.patch | 19 + .../005.02-gpu-cpu-opp-table-updates.patch | 76 + ...-Update-cache-properties-for-amlogic.patch | 99 + ...amlogic-add-missing-cache-properties.patch | 95 + ...-internal-PCM-chmap-ELD-IEC958-kctl.patch} | 2 +- 18 files changed, 4179 insertions(+), 3997 deletions(-) rename projects/Amlogic/packages/linux/patches/S922X/{004-dts-to-compile.patch => 001.01-device-trees-to-build.patch} (90%) create mode 100644 projects/Amlogic/packages/linux/patches/S922X/001.02-Add-ODROID-GO-Ultra-device-tree.patch create mode 100644 projects/Amlogic/packages/linux/patches/S922X/001.03-Add-Powkiddy-RGB10-MAX-3-device-tree.patch rename projects/Amlogic/packages/linux/patches/S922X/{001-mali-gpu-r44.patch => 002.01-Add-Mali-GPU-r44-driver.patch} (100%) create mode 100644 projects/Amlogic/packages/linux/patches/S922X/002.02-Add-Mali-to-device-trees.patch create mode 100644 projects/Amlogic/packages/linux/patches/S922X/003.01-ODROID-N2-heartbeat-quirk.patch create mode 100644 projects/Amlogic/packages/linux/patches/S922X/003.02-DRM-panel-orientation-quirk.patch create mode 100644 projects/Amlogic/packages/linux/patches/S922X/004.01-ODROID-GO-Ultra-joypad-driver.patch create mode 100644 projects/Amlogic/packages/linux/patches/S922X/004.02-ODROID-GO-Ultra-power-off-driver.patch create mode 100644 projects/Amlogic/packages/linux/patches/S922X/004.03-polled-input-device-driver.patch rename projects/Amlogic/packages/linux/patches/S922X/{000-s922x-devices.patch => 004.04-rk818-charger-driver.patch} (56%) rename projects/Amlogic/packages/linux/patches/S922X/{003-dsi-driver.patch => 004.05-dsi-driver.patch} (99%) create mode 100644 projects/Amlogic/packages/linux/patches/S922X/004.06-digital-volume-is-limited-to.patch create mode 100644 projects/Amlogic/packages/linux/patches/S922X/005.01-add-uart-ao-b-pins-to-device-trees.patch create mode 100644 projects/Amlogic/packages/linux/patches/S922X/005.02-gpu-cpu-opp-table-updates.patch create mode 100644 projects/Amlogic/packages/linux/patches/S922X/999.01-arm64-dts-Update-cache-properties-for-amlogic.patch create mode 100644 projects/Amlogic/packages/linux/patches/S922X/999.02-arm64-dts-amlogic-add-missing-cache-properties.patch rename projects/Amlogic/packages/linux/patches/S922X/{002-controls.patch => 999.03-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch} (97%) diff --git a/projects/Amlogic/packages/linux/patches/S922X/004-dts-to-compile.patch b/projects/Amlogic/packages/linux/patches/S922X/001.01-device-trees-to-build.patch similarity index 90% rename from projects/Amlogic/packages/linux/patches/S922X/004-dts-to-compile.patch rename to projects/Amlogic/packages/linux/patches/S922X/001.01-device-trees-to-build.patch index da7e3fd98..5d0bf6473 100644 --- a/projects/Amlogic/packages/linux/patches/S922X/004-dts-to-compile.patch +++ b/projects/Amlogic/packages/linux/patches/S922X/001.01-device-trees-to-build.patch @@ -1,6 +1,7 @@ ---- a/arch/arm64/boot/dts/amlogic/Makefile -+++ b/arch/arm64/boot/dts/amlogic/Makefile -@@ -1,71 +1,5 @@ +diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/Makefile linux/arch/arm64/boot/dts/amlogic/Makefile +--- linux.orig/arch/arm64/boot/dts/amlogic/Makefile 2023-09-12 12:02:56.937601871 +0000 ++++ linux/arch/arm64/boot/dts/amlogic/Makefile 2023-09-12 12:03:27.490291628 +0000 +@@ -1,69 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-axg-jethome-jethub-j100.dtb @@ -15,10 +16,9 @@ -dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gsking-x.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking-pro.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-go-ultra.dtb ++dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-go-ultra.dtb dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2-plus.dtb dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-powkiddy-rgb10-max-3.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-g12b-ugoos-am6.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-kii-pro.dtb @@ -72,3 +72,4 @@ -dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air-gbit.dtb -dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air.dtb ++dtb-$(CONFIG_ARCH_MESON) += meson-g12b-powkiddy-rgb10-max-3.dtb diff --git a/projects/Amlogic/packages/linux/patches/S922X/001.02-Add-ODROID-GO-Ultra-device-tree.patch b/projects/Amlogic/packages/linux/patches/S922X/001.02-Add-ODROID-GO-Ultra-device-tree.patch new file mode 100644 index 000000000..6e7fed000 --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/001.02-Add-ODROID-GO-Ultra-device-tree.patch @@ -0,0 +1,1025 @@ +diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts linux/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts +--- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts 1970-01-01 00:00:00.000000000 +0000 ++++ linux/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts 2023-09-12 13:20:28.956694441 +0000 +@@ -0,0 +1,1021 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2022 Neil Armstrong ++ */ ++ ++/dts-v1/; ++ ++#include "meson-g12b-s922x.dtsi" ++#include ++#include ++#include ++#include ++#include ++ ++/ { ++ compatible = "hardkernel,odroid-go-ultra", "amlogic,s922x", "amlogic,g12b"; ++ model = "Hardkernel ODROID-GO-Ultra"; ++ ++ aliases { ++ serial0 = &uart_AO; ++ rtc0 = &vrtc; ++ mmc0 = &sd_emmc_c; ++ mmc1 = &sd_emmc_b; ++ }; ++ ++ panel_backlight: backlight { ++ compatible = "pwm-backlight"; ++ pwms = <&pwm_ef 1 40000 0>; ++ brightness-levels = <0 255>; ++ num-interpolated-steps = <255>; ++ default-brightness-level = <255>; ++ }; ++ ++ bat: battery { ++ compatible = "simple-battery"; ++ voltage-max-design-microvolt = <4200000>; ++ voltage-min-design-microvolt = <3500000>; ++ charge-full-design-microamp-hours = <4000000>; ++ charge-term-current-microamp = <200000>; ++ constant-charge-current-max-microamp = <1500000>; ++ constant-charge-voltage-max-microvolt = <4200000>; ++ factory-internal-resistance-micro-ohms = <180000>; ++ ++ ++ ocv-capacity-celsius = <20>; ++ ocv-capacity-table-0 = <4146950 100>, <4001920 95>, <3967900 90>, <3919950 85>, ++ <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, ++ <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, ++ <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, ++ <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, ++ <3574170 0>; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ codec_clk: codec-clk { ++ compatible = "fixed-clock"; ++ clock-frequency = <12288000>; ++ clock-output-names = "codec_clk"; ++ #clock-cells = <0>; ++ }; ++ ++ gpio_keys: volume-keys { ++ compatible = "gpio-keys-polled"; ++ poll-interval = <5>; ++ autorepeat; ++ ++ volume-up-button { ++ label = "VOLUME-UP"; ++ linux,code = ; ++ gpios = <&gpio GPIOX_8 GPIO_ACTIVE_LOW>; ++ }; ++ volume-down-button { ++ label = "VOLUME-DOWN"; ++ linux,code = ; ++ gpios = <&gpio GPIOX_9 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ hp_detect_switch: hp-detect-switch { ++ compatible = "gpio-keys-polled"; ++ poll-interval = <5>; ++ autorepeat; ++ ++ hp-detect-pin { ++ label = "HEADPHONE"; ++ linux,input-type = ; ++ linux,code = ; ++ gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ ++ joypad: gou_joypad { ++ compatible = "odroidgou-joypad"; ++ poll-interval = <10>; ++ pinctrl-0 = <&keypad_gpio_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ joypad-name = "GO-Ultra Gamepad"; ++ //joypad-vendor = <0x045e>; ++ joypad-product = <0x1000>; ++ joypad-revision = <0x0100>; ++ ++ /* Analog sticks */ ++ io-channels = <&saradc 0>, <&saradc 1>, <&saradc 2>, <&saradc 3>; ++ io-channel-names = "key-RY", "key-RX", "key-LY", "key-LX"; ++ button-adc-scale = <4>; ++ button-adc-deadzone = <64>; ++ button-adc-fuzz = <32>; ++ button-adc-flat = <32>; ++ abs_x-p-tuning = <350>; ++ abs_x-n-tuning = <350>; ++ abs_y-p-tuning = <350>; ++ abs_y-n-tuning = <350>; ++ abs_rx-p-tuning = <350>; ++ abs_rx-n-tuning = <350>; ++ abs_ry-p-tuning = <350>; ++ abs_ry-n-tuning = <350>; ++ ++ /* Buttons */ ++ sw1 { ++ gpios = <&gpio GPIOX_0 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-UP"; ++ linux,code = ; // 0x220 ++ }; ++ sw2 { ++ gpios = <&gpio GPIOX_1 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-DOWN"; ++ linux,code = ; // 0x221 ++ }; ++ sw3 { ++ gpios = <&gpio GPIOX_2 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-LEFT"; ++ linux,code = ; // 0x222 ++ }; ++ sw4 { ++ gpios = <&gpio GPIOX_3 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-RIGHT"; ++ linux,code = ; // 0x223 ++ }; ++ sw5 { ++ gpios = <&gpio GPIOX_4 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-A"; ++ linux,code = ; // 0x131 ++ }; ++ sw6 { ++ gpios = <&gpio GPIOX_5 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-B"; ++ linux,code = ; // 0x130 ++ }; ++ sw7 { ++ gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-Y"; ++ linux,code = ; // 0x134 ++ }; ++ sw8 { ++ gpios = <&gpio GPIOX_7 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-X"; ++ linux,code = ; // 0x133 ++ }; ++ sw11 { ++ gpios = <&gpio GPIOX_10 GPIO_ACTIVE_LOW>; ++ label = "GPIO F2"; ++ linux,code = ; // 0x2c2 ++ }; ++ sw12 { ++ gpios = <&gpio GPIOX_11 GPIO_ACTIVE_LOW>; ++ label = "GPIO F3"; ++ linux,code = ; // 0x2c3 ++ }; ++ sw13 { ++ gpios = <&gpio GPIOX_12 GPIO_ACTIVE_LOW>; ++ label = "GPIO F4"; ++ linux,code = ; // 0x2c4 ++ }; ++ sw14 { ++ gpios = <&gpio GPIOX_13 GPIO_ACTIVE_LOW>; ++ label = "GPIO F5"; ++ linux,code = ; // 0x13c ++ }; ++ sw15 { ++ gpios = <&gpio GPIOX_14 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-LEFT"; ++ linux,code = ; // 0x02 ++ }; ++ sw16 { ++ gpios = <&gpio GPIOX_15 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-RIGHT"; ++ linux,code = ; // 0x05 ++ }; ++ sw17 { ++ gpios = <&gpio GPIOX_16 GPIO_ACTIVE_LOW>; ++ label = "GPIO F6"; ++ linux,code = ; ++ }; ++ sw18 { ++ gpios = <&gpio GPIOX_17 GPIO_ACTIVE_LOW>; ++ label = "GPIO F1"; ++ linux,code = ; ++ }; ++ sw19 { ++ gpios = <&gpio GPIOX_18 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-RIGHT2"; ++ linux,code = ; ++ }; ++ sw20 { ++ gpios = <&gpio GPIOX_19 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-LEFT2"; ++ linux,code = ; ++ }; ++ }; ++ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x40000000>; ++ }; ++ ++ emmc_pwrseq: emmc-pwrseq { ++ compatible = "mmc-pwrseq-emmc"; ++ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-blue { ++ color = ; ++ function = LED_FUNCTION_STATUS; ++ gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "none"; ++ }; ++ ++ led-red { ++ color = ; ++ function = LED_FUNCTION_STATUS; ++ gpios = <&gpio_ao GPIOAO_6 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ ++ poweroff { ++ compatible = "hardkernel,odroid-go-ultra-poweroff"; ++ hardkernel,rk817-pmic = <&rk817>; ++ hardkernel,rk818-pmic = <&rk818>; ++ }; ++ ++ vdd_sys: regulator-vdd_sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "VDD_SYS"; ++ regulator-min-microvolt = <3800000>; ++ regulator-max-microvolt = <3800000>; ++ regulator-always-on; ++ }; ++ ++ sound { ++ compatible = "amlogic,axg-sound-card"; ++ model = "ODROID-GO-ULTRA"; ++ audio-aux-devs = <&tdmout_b>; ++ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", ++ "TDM_B Playback", "TDMOUT_B OUT"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ status = "okay"; ++ ++ dai-link-0 { ++ sound-dai = <&frddr_a>; ++ }; ++ ++ dai-link-1 { ++ sound-dai = <&frddr_b>; ++ }; ++ ++ dai-link-2 { ++ sound-dai = <&frddr_c>; ++ }; ++ ++ dai-link-3 { ++ sound-dai = <&toddr_a>; ++ }; ++ ++ dai-link-4 { ++ sound-dai = <&toddr_b>; ++ }; ++ ++ dai-link-5 { ++ sound-dai = <&toddr_c>; ++ }; ++ ++ /* 8ch hdmi interface */ ++ dai-link-6 { ++ sound-dai = <&tdmif_b>; ++ dai-format = "i2s"; ++ dai-tdm-slot-tx-mask-0 = <1 1>; ++ dai-tdm-slot-tx-mask-1 = <1 1>; ++ mclk-fs = <256>; ++ ++ codec-0 { ++ sound-dai = <&rk817>; ++ }; ++ }; ++ }; ++}; ++ ++&arb { ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vddcpu_b>; ++ operating-points-v2 = <&cpu_opp_table_0>; ++ clocks = <&clkc CLKID_CPU_CLK>; ++ clock-latency = <50000>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vddcpu_b>; ++ operating-points-v2 = <&cpu_opp_table_0>; ++ clocks = <&clkc CLKID_CPU_CLK>; ++ clock-latency = <50000>; ++}; ++ ++&cpu100 { ++ cpu-supply = <&vddcpu_a>; ++ operating-points-v2 = <&cpub_opp_table_1>; ++ clocks = <&clkc CLKID_CPUB_CLK>; ++ clock-latency = <50000>; ++}; ++ ++&cpu101 { ++ cpu-supply = <&vddcpu_a>; ++ operating-points-v2 = <&cpub_opp_table_1>; ++ clocks = <&clkc CLKID_CPUB_CLK>; ++ clock-latency = <50000>; ++}; ++ ++&cpu102 { ++ cpu-supply = <&vddcpu_a>; ++ operating-points-v2 = <&cpub_opp_table_1>; ++ clocks = <&clkc CLKID_CPUB_CLK>; ++ clock-latency = <50000>; ++}; ++ ++&cpu103 { ++ cpu-supply = <&vddcpu_a>; ++ operating-points-v2 = <&cpub_opp_table_1>; ++ clocks = <&clkc CLKID_CPUB_CLK>; ++ clock-latency = <50000>; ++}; ++ ++/* RK817 only supports 12.5mV steps, round up the values */ ++&cpu_opp_table_0 { ++ opp-667000000 { ++ opp-microvolt = <725000>; ++ }; ++ opp-1000000000 { ++ opp-microvolt = <737500>; ++ }; ++ opp-1200000000 { ++ opp-microvolt = <737500>; ++ }; ++ opp-1398000000 { ++ opp-microvolt = <762500>; ++ }; ++ opp-1512000000 { ++ opp-microvolt = <800000>; ++ }; ++ opp-1608000000 { ++ opp-microvolt = <837500>; ++ }; ++ opp-1704000000 { ++ opp-microvolt = <862500>; ++ }; ++ opp-1896000000 { ++ opp-microvolt = <987500>; ++ }; ++ opp-1992000000 { ++ opp-microvolt = <1050000>; ++ }; ++ opp-2016000000 { ++ opp-hz = /bits/ 64 <2016000000>; ++ opp-microvolt = <1050000>; ++ }; ++}; ++ ++/* RK818 only supports 12.5mV steps, round up the values */ ++&cpub_opp_table_1 { ++ opp-667000000 { ++ opp-microvolt = <750000>; ++ }; ++ opp-1000000000 { ++ opp-microvolt = <775000>; ++ }; ++ opp-1200000000 { ++ opp-microvolt = <775000>; ++ }; ++ opp-1398000000 { ++ opp-microvolt = <800000>; ++ }; ++ opp-1512000000 { ++ opp-microvolt = <825000>; ++ }; ++ opp-1608000000 { ++ opp-microvolt = <862500>; ++ }; ++ opp-1704000000 { ++ opp-microvolt = <900000>; ++ }; ++ opp-1800000000 { ++ opp-microvolt = <987500>; ++ }; ++ opp-1908000000 { ++ opp-microvolt = <1025000>; ++ }; ++ opp-2016000000 { ++ opp-hz = /bits/ 64 <2016000000>; ++ opp-microvolt = <1025000>; ++ }; ++ opp-2100000000 { ++ opp-hz = /bits/ 64 <2100000000>; ++ opp-microvolt = <1025000>; ++ }; ++ opp-2208000000 { ++ opp-hz = /bits/ 64 <2208000000>; ++ opp-microvolt = <1050000>; ++ }; ++ opp-2304000000 { ++ opp-hz = /bits/ 64 <2304000000>; ++ opp-microvolt = <1050000>; ++ }; ++ opp-2400000000 { ++ opp-hz = /bits/ 64 <2400000000>; ++ opp-microvolt = <1050000>; ++ }; ++}; ++ ++&i2c_AO { ++ status = "okay"; ++ pinctrl-0 = <&i2c_ao_sck_pins>, <&i2c_ao_sda_pins>; ++ pinctrl-names = "default"; ++ ++ rk818: pmic@1c { ++ compatible = "rockchip,rk818"; ++ reg = <0x1c>; ++ interrupt-parent = <&gpio_intc>; ++ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; /* GPIOAO_7 */ ++ rockchip,system-power-controller; ++ clock-output-names = "rk808-clkout1", "rk808-clkout2"; ++ ++ vcc1-supply = <&vdd_sys>; ++ vcc2-supply = <&vdd_sys>; ++ vcc3-supply = <&vdd_sys>; ++ vcc4-supply = <&vdd_sys>; ++ vcc6-supply = <&vdd_sys>; ++ vcc7-supply = <&vcc_2v3>; ++ vcc8-supply = <&vcc_2v3>; ++ vcc9-supply = <&vddao_3v3>; ++ boost-supply = <&vdd_sys>; ++ switch-supply = <&vdd_sys>; ++ ++ regulators { ++ vddcpu_a: DCDC_REG1 { ++ regulator-name = "vddcpu_a"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <750000>; ++ }; ++ }; ++ ++ vdd_ee: DCDC_REG2 { ++ regulator-name = "vdd_ee"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <875000>; ++ regulator-max-microvolt = <900000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <875000>; ++ }; ++ }; ++ ++ vddq_1v1: DCDC_REG3 { ++ regulator-name = "vddq_1v1"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vddao_3v3: DCDC_REG4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vddao_3v3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ hp_5v: DCDC_BOOST { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "hp_5v"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG1 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO1"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG2 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO2"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG3 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO3"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG4 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO4"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vddio_ao1v8: LDO_REG5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vddio_ao1v8"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ LDO_REG6 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO6"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vddq_1v8: LDO_REG7 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vddq_1v8"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ LDO_REG8 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO8"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vddio_c: LDO_REG9 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vddio_c"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_sd: SWITCH_REG { ++ regulator-name = "vcc_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ rk818_otg_switch: OTG_SWITCH { ++ regulator-name = "otg_switch"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ ++ battery { ++ compatible = "rockchip,rk818-battery"; ++ ++ ocv_table = < ++ 3470 3599 3671 3701 3728 3746 3762 ++ 3772 3781 3792 3816 3836 3866 3910 ++ 3942 3971 4002 4050 4088 4132 4200>; ++ design_capacity = <4000>; ++ design_qmax = <4100>; ++ bat_res = <180>; ++ max_input_current = <2000>; ++ max_chrg_current = <1500>; ++ max_chrg_voltage = <4250>; ++ sleep_enter_current = <300>; ++ sleep_exit_current = <300>; ++ power_off_thresd = <3450>; ++ zero_algorithm_vol = <3700>; ++ fb_temperature = <105>; ++ sample_res = <10>; ++ max_soc_offset = <60>; ++ energy_mode = <0>; ++ monitor_sec = <5>; ++ virtual_power = <0>; ++ power_dc2otg = <0>; ++ otg5v_suspend_enable = <0>; ++ }; ++ ++ charger { ++ compatible = "rockchip,rk818-charger"; ++ monitored-battery = <&bat>; ++ }; ++ ++ }; ++}; ++ ++&i2c3 { ++ status = "okay"; ++ pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>; ++ pinctrl-names = "default"; ++ ++ rk817: pmic@20 { ++ compatible = "rockchip,rk817"; ++ reg = <0x20>; ++ status = "okay"; ++ interrupt-parent = <&gpio_intc>; ++ interrupts = <5 IRQ_TYPE_LEVEL_LOW>; /* GPIOAO_5 */ ++ wakeup-source; ++ ++ vcc1-supply = <&vdd_sys>; ++ vcc2-supply = <&vdd_sys>; ++ vcc3-supply = <&vdd_sys>; ++ vcc4-supply = <&vdd_sys>; ++ vcc5-supply = <&vdd_sys>; ++ vcc6-supply = <&vdd_sys>; ++ vcc7-supply = <&vdd_sys>; ++ vcc8-supply = <&vdd_sys>; ++ vcc9-supply = <&rk817_boost>; ++ ++ #sound-dai-cells = <0>; ++ clocks = <&codec_clk>; ++ clock-names = "mclk"; ++ ++ regulators { ++ DCDC_REG1 { ++ regulator-boot-off; ++ regulator-name = "rk817_BUCK1"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vddcpu_b: DCDC_REG2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <725000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-ramp-delay = <6001>; ++ regulator-initial-mode = <0x2>; ++ regulator-name = "vddcpu_b"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vcc_2v3: DCDC_REG3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <2300000>; ++ regulator-max-microvolt = <2400000>; ++ regulator-initial-mode = <0x2>; ++ regulator-name = "vcc_2v3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ DCDC_REG4 { ++ regulator-boot-off; ++ regulator-name = "rk817_BUCK4"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG1 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO1"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG2 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO2"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG3 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO3"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vdd_codec"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG5 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO5"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG6 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO6"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG7 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO7"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_lcd: LDO_REG8 { ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vcc_lcd"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG9 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO9"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk817_boost: BOOST { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5400000>; ++ regulator-name = "rk817_boost"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ usb_host: OTG_SWITCH { ++ regulator-name = "usb_host"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ ++ rk817_codec: codec { ++ rockchip,mic-in-differential; ++ }; ++ }; ++}; ++ ++&clkc_audio { ++ status = "okay"; ++}; ++ ++ð_phy { ++ status = "disabled"; ++}; ++ ++&frddr_a { ++ status = "okay"; ++}; ++ ++&frddr_b { ++ status = "okay"; ++}; ++ ++&frddr_c { ++ status = "okay"; ++}; ++ ++&toddr_a { ++ status = "okay"; ++}; ++ ++&toddr_b { ++ status = "okay"; ++}; ++ ++&toddr_c { ++ status = "okay"; ++}; ++ ++&mipi_dsi { ++ status = "okay"; ++ ++ assigned-clocks = <&clkc CLKID_GP0_PLL>, ++ <&clkc CLKID_MIPI_DSI_PXCLK_SEL>, ++ <&clkc CLKID_MIPI_DSI_PXCLK>, ++ <&clkc CLKID_CTS_ENCL_SEL>, ++ <&clkc CLKID_VCLK2_SEL>; ++ assigned-clock-parents = <0>, ++ <&clkc CLKID_GP0_PLL>, ++ <0>, ++ <&clkc CLKID_VCLK2_DIV1>, ++ <&clkc CLKID_GP0_PLL>; ++ assigned-clock-rates = <344976000>, ++ <0>, ++ <344976000>, ++ <0>, ++ <0>; ++ ++ panel@0 { ++ compatible = "elida,kd50t048a", "sitronix,st7701"; ++ reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_HIGH>; ++ IOVCC-supply = <&vcc_lcd>; ++ VCC-supply = <&vcc_lcd>; ++ backlight = <&panel_backlight>; ++ rotation = <270>; ++ reg = <0>; ++ ++ port { ++ mipi_in_panel: endpoint { ++ remote-endpoint = <&mipi_out_panel>; ++ }; ++ }; ++ }; ++}; ++ ++&mipi_analog_dphy { ++ status = "okay"; ++}; ++ ++&mipi_dphy { ++ status = "okay"; ++}; ++ ++&mipi_dsi_panel_port { ++ mipi_out_panel: endpoint { ++ remote-endpoint = <&mipi_in_panel>; ++ }; ++}; ++ ++&periphs_pinctrl { ++ keypad_gpio_pins: keypad-gpio { ++ mux { ++ groups = "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", ++ "GPIOX_4", "GPIOX_5", "GPIOX_6", "GPIOX_7", ++ "GPIOX_8", "GPIOX_9", "GPIOX_10", "GPIOX_11", ++ "GPIOX_12", "GPIOX_13", "GPIOX_14", "GPIOX_15", ++ "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19"; ++ function = "gpio_periphs"; ++ bias-pull-up; ++ output-disable; ++ }; ++ }; ++}; ++ ++&pwm_ef { ++ status = "okay"; ++ pinctrl-0 = <&pwm_f_h_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&saradc { ++ status = "okay"; ++ vref-supply = <&vddio_ao1v8>; ++}; ++ ++/* SD card */ ++&sd_emmc_b { ++ status = "okay"; ++ pinctrl-0 = <&sdcard_c_pins>; ++ pinctrl-1 = <&sdcard_clk_gate_c_pins>; ++ pinctrl-names = "default", "clk-gate"; ++ ++ bus-width = <4>; ++ cap-sd-highspeed; ++ max-frequency = <50000000>; ++ disable-wp; ++ ++ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vddio_c>; ++ ++}; ++ ++/* eMMC */ ++&sd_emmc_c { ++ status = "okay"; ++ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; ++ pinctrl-1 = <&emmc_clk_gate_pins>; ++ pinctrl-names = "default", "clk-gate"; ++ ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ max-frequency = <200000000>; ++ disable-wp; ++ ++ mmc-pwrseq = <&emmc_pwrseq>; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vddio_ao1v8>; ++}; ++ ++ ++&tdmif_b { ++ pinctrl-0 = <&mclk0_a_pins>, <&tdm_b_fs_pins>, <&tdm_b_sclk_pins>, ++ <&tdm_b_dout0_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ assigned-clocks = <&clkc_audio AUD_CLKID_TDM_MCLK_PAD0>, ++ <&clkc_audio AUD_CLKID_TDM_SCLK_PAD1>, ++ <&clkc_audio AUD_CLKID_TDM_LRCLK_PAD1>; ++ assigned-clock-parents = <&clkc_audio AUD_CLKID_MST_B_MCLK>, ++ <&clkc_audio AUD_CLKID_MST_B_SCLK>, ++ <&clkc_audio AUD_CLKID_MST_B_LRCLK>; ++ assigned-clock-rates = <0>, <0>, <0>; ++}; ++ ++&tdmout_b { ++ status = "okay"; ++}; ++ ++&uart_AO { ++ status = "okay"; ++ pinctrl-0 = <&uart_ao_a_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&usb { ++ status = "okay"; ++ dr_mode = "peripheral"; ++}; ++ ++&usb2_phy0 { ++ status = "okay"; ++}; ++ ++&usb2_phy1 { ++ status = "okay"; ++ phy-supply = <&usb_host>; ++}; diff --git a/projects/Amlogic/packages/linux/patches/S922X/001.03-Add-Powkiddy-RGB10-MAX-3-device-tree.patch b/projects/Amlogic/packages/linux/patches/S922X/001.03-Add-Powkiddy-RGB10-MAX-3-device-tree.patch new file mode 100644 index 000000000..d4649c2c0 --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/001.03-Add-Powkiddy-RGB10-MAX-3-device-tree.patch @@ -0,0 +1,999 @@ +diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts linux/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts +--- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts 1970-01-01 00:00:00.000000000 +0000 ++++ linux/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts 2023-09-12 12:04:13.567330573 +0000 +@@ -0,0 +1,995 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2022 Neil Armstrong ++ * Copyright (C) 2022-present - The JELOS Project (https://github.com/JustEnoughLinuxOS) ++ */ ++ ++/dts-v1/; ++ ++#include "meson-g12b-a311d.dtsi" ++#include ++#include ++#include ++#include ++#include ++ ++/ { ++ compatible = "powkiddy,rgb10-max-3", "amlogic,s922x", "amlogic,g12b"; ++ model = "Powkiddy RGB10 MAX 3"; ++ ++ aliases { ++ serial0 = &uart_AO; ++ rtc0 = &vrtc; ++ mmc0 = &sd_emmc_c; ++ mmc1 = &sd_emmc_b; ++ }; ++ ++ panel_backlight: backlight { ++ compatible = "pwm-backlight"; ++ pwms = <&pwm_ef 1 40000 0>; ++ brightness-levels = <0 255>; ++ num-interpolated-steps = <255>; ++ default-brightness-level = <255>; ++ }; ++ ++ bat: battery { ++ compatible = "simple-battery"; ++ voltage-max-design-microvolt = <4200000>; ++ voltage-min-design-microvolt = <3500000>; ++ charge-full-design-microamp-hours = <4000000>; ++ charge-term-current-microamp = <200000>; ++ constant-charge-current-max-microamp = <1500000>; ++ constant-charge-voltage-max-microvolt = <4200000>; ++ factory-internal-resistance-micro-ohms = <180000>; ++ ++ ++ ocv-capacity-celsius = <20>; ++ ocv-capacity-table-0 = <4146950 100>, <4001920 95>, <3967900 90>, <3919950 85>, ++ <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, ++ <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, ++ <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, ++ <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, ++ <3574170 0>; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ codec_clk: codec-clk { ++ compatible = "fixed-clock"; ++ clock-frequency = <12288000>; ++ clock-output-names = "codec_clk"; ++ #clock-cells = <0>; ++ }; ++ ++ gpio_keys: volume-keys { ++ compatible = "gpio-keys-polled"; ++ poll-interval = <5>; ++ autorepeat; ++ ++ volume-up-button { ++ label = "VOLUME-UP"; ++ linux,code = ; ++ gpios = <&gpio GPIOX_8 GPIO_ACTIVE_LOW>; ++ }; ++ volume-down-button { ++ label = "VOLUME-DOWN"; ++ linux,code = ; ++ gpios = <&gpio GPIOX_9 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ joypad: gou_joypad { ++ compatible = "odroidgou-joypad"; ++ poll-interval = <10>; ++ pinctrl-0 = <&keypad_gpio_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ joypad-name = "GO-Ultra Gamepad"; ++ //joypad-vendor = <0x045e>; ++ joypad-product = <0x1000>; ++ joypad-revision = <0x0100>; ++ ++ /* Analog sticks */ ++ ++ io-channels = <&saradc 0>, <&saradc 1>, <&saradc 2>, <&saradc 3>; ++ io-channel-names = "key-RY", "key-RX", "key-LY", "key-LX"; ++ button-adc-scale = <4>; ++ button-adc-deadzone = <400>; ++ button-adc-fuzz = <64>; ++ button-adc-flat = <32>; ++ abs_x-p-tuning = <350>; ++ abs_x-n-tuning = <350>; ++ abs_y-p-tuning = <350>; ++ abs_y-n-tuning = <350>; ++ abs_rx-p-tuning = <350>; ++ abs_rx-n-tuning = <350>; ++ abs_ry-p-tuning = <350>; ++ abs_ry-n-tuning = <350>; ++ ++ /* Buttons */ ++ sw1 { ++ gpios = <&gpio GPIOX_0 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-UP"; ++ linux,code = ; // 0x220 ++ }; ++ sw2 { ++ gpios = <&gpio GPIOX_1 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-DOWN"; ++ linux,code = ; // 0x221 ++ }; ++ sw3 { ++ gpios = <&gpio GPIOX_2 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-LEFT"; ++ linux,code = ; // 0x222 ++ }; ++ sw4 { ++ gpios = <&gpio GPIOX_3 GPIO_ACTIVE_LOW>; ++ label = "GPIO DPAD-RIGHT"; ++ linux,code = ; // 0x223 ++ }; ++ sw5 { ++ gpios = <&gpio GPIOX_4 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-A"; ++ linux,code = ; // 0x131 ++ }; ++ sw6 { ++ gpios = <&gpio GPIOX_5 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-B"; ++ linux,code = ; // 0x130 ++ }; ++ sw7 { ++ gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-Y"; ++ linux,code = ; // 0x134 ++ }; ++ sw8 { ++ gpios = <&gpio GPIOX_7 GPIO_ACTIVE_LOW>; ++ label = "GPIO BTN-X"; ++ linux,code = ; // 0x133 ++ }; ++ sw11 { ++ gpios = <&gpio GPIOX_10 GPIO_ACTIVE_LOW>; ++ label = "GPIO F2"; ++ linux,code = ; // 0x2c2 ++ }; ++ sw12 { ++ gpios = <&gpio GPIOX_17 GPIO_ACTIVE_LOW>; ++ label = "GPIO F3"; ++ linux,code = ; // 0x2c3 ++ }; ++ sw13 { ++ gpios = <&gpio GPIOX_16 GPIO_ACTIVE_LOW>; ++ label = "GPIO F4"; ++ linux,code = ; // 0x2c4 ++ }; ++ sw14 { ++ gpios = <&gpio GPIOX_11 GPIO_ACTIVE_LOW>; ++ label = "GPIO F5"; ++ linux,code = ; // 0x13c ++ }; ++ sw15 { ++ gpios = <&gpio GPIOX_14 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-LEFT"; ++ linux,code = ; // 0x02 ++ }; ++ sw16 { ++ gpios = <&gpio GPIOX_15 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-RIGHT"; ++ linux,code = ; // 0x05 ++ }; ++ sw17 { ++ gpios = <&gpio GPIOX_13 GPIO_ACTIVE_LOW>; ++ label = "GPIO F6"; ++ linux,code = ; ++ }; ++ sw18 { ++ gpios = <&gpio GPIOX_12 GPIO_ACTIVE_LOW>; ++ label = "GPIO F1"; ++ linux,code = ; ++ }; ++ sw19 { ++ gpios = <&gpio GPIOX_18 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-RIGHT2"; ++ linux,code = ; ++ }; ++ sw20 { ++ gpios = <&gpio GPIOX_19 GPIO_ACTIVE_LOW>; ++ label = "GPIO TOP-LEFT2"; ++ linux,code = ; ++ }; ++ }; ++ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x40000000>; ++ }; ++ ++ emmc_pwrseq: emmc-pwrseq { ++ compatible = "mmc-pwrseq-emmc"; ++ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-blue { ++ color = ; ++ function = LED_FUNCTION_STATUS; ++ gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "none"; ++ }; ++ ++ led-red { ++ color = ; ++ function = LED_FUNCTION_STATUS; ++ gpios = <&gpio_ao GPIOAO_6 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ ++ poweroff { ++ compatible = "hardkernel,odroid-go-ultra-poweroff"; ++ hardkernel,rk817-pmic = <&rk817>; ++ hardkernel,rk818-pmic = <&rk818>; ++ }; ++ ++ vdd_sys: regulator-vdd_sys { ++ compatible = "regulator-fixed"; ++ regulator-name = "VDD_SYS"; ++ regulator-min-microvolt = <3800000>; ++ regulator-max-microvolt = <3800000>; ++ regulator-always-on; ++ }; ++ ++ sound { ++ compatible = "amlogic,axg-sound-card"; ++ model = "RGB10-MAX3"; ++ audio-aux-devs = <&tdmout_b>; ++ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", ++ "TDM_B Playback", "TDMOUT_B OUT"; ++ ++ assigned-clocks = <&clkc CLKID_MPLL2>, ++ <&clkc CLKID_MPLL0>, ++ <&clkc CLKID_MPLL1>; ++ assigned-clock-parents = <0>, <0>, <0>; ++ assigned-clock-rates = <294912000>, ++ <270950400>, ++ <393216000>; ++ status = "okay"; ++ ++ dai-link-0 { ++ sound-dai = <&frddr_a>; ++ }; ++ ++ dai-link-1 { ++ sound-dai = <&frddr_b>; ++ }; ++ ++ dai-link-2 { ++ sound-dai = <&frddr_c>; ++ }; ++ ++ dai-link-3 { ++ sound-dai = <&toddr_a>; ++ }; ++ ++ dai-link-4 { ++ sound-dai = <&toddr_b>; ++ }; ++ ++ dai-link-5 { ++ sound-dai = <&toddr_c>; ++ }; ++ ++ /* 8ch hdmi interface */ ++ dai-link-6 { ++ sound-dai = <&tdmif_b>; ++ dai-format = "i2s"; ++ dai-tdm-slot-tx-mask-0 = <1 1>; ++ dai-tdm-slot-tx-mask-1 = <1 1>; ++ mclk-fs = <256>; ++ ++ codec-0 { ++ sound-dai = <&rk817>; ++ }; ++ }; ++ }; ++}; ++ ++&arb { ++ status = "okay"; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vddcpu_b>; ++ operating-points-v2 = <&cpu_opp_table_0>; ++ clocks = <&clkc CLKID_CPU_CLK>; ++ clock-latency = <50000>; ++}; ++ ++&cpu1 { ++ cpu-supply = <&vddcpu_b>; ++ operating-points-v2 = <&cpu_opp_table_0>; ++ clocks = <&clkc CLKID_CPU_CLK>; ++ clock-latency = <50000>; ++}; ++ ++&cpu100 { ++ cpu-supply = <&vddcpu_a>; ++ operating-points-v2 = <&cpub_opp_table_1>; ++ clocks = <&clkc CLKID_CPUB_CLK>; ++ clock-latency = <50000>; ++}; ++ ++&cpu101 { ++ cpu-supply = <&vddcpu_a>; ++ operating-points-v2 = <&cpub_opp_table_1>; ++ clocks = <&clkc CLKID_CPUB_CLK>; ++ clock-latency = <50000>; ++}; ++ ++&cpu102 { ++ cpu-supply = <&vddcpu_a>; ++ operating-points-v2 = <&cpub_opp_table_1>; ++ clocks = <&clkc CLKID_CPUB_CLK>; ++ clock-latency = <50000>; ++}; ++ ++&cpu103 { ++ cpu-supply = <&vddcpu_a>; ++ operating-points-v2 = <&cpub_opp_table_1>; ++ clocks = <&clkc CLKID_CPUB_CLK>; ++ clock-latency = <50000>; ++}; ++ ++/* RK817 only supports 12.5mV steps, round up the values */ ++&cpu_opp_table_0 { ++ opp-667000000 { ++ opp-microvolt = <731250>; ++ }; ++ opp-1000000000 { ++ opp-microvolt = <760000>; ++ }; ++ opp-1200000000 { ++ opp-microvolt = <780000>; ++ }; ++ opp-1398000000 { ++ opp-microvolt = <800000>; ++ }; ++ opp-1512000000 { ++ opp-microvolt = <860000>; ++ }; ++ opp-1608000000 { ++ opp-microvolt = <900000>; ++ }; ++ opp-1704000000 { ++ opp-microvolt = <950000>; ++ }; ++ opp-1800000000 { ++ opp-microvolt = <1000000>; ++ }; ++}; ++ ++/* RK818 only supports 12.5mV steps, round up the values */ ++&cpub_opp_table_1 { ++ opp-667000000 { ++ opp-microvolt = <750000>; ++ }; ++ opp-1000000000 { ++ opp-microvolt = <775000>; ++ }; ++ opp-1200000000 { ++ opp-microvolt = <775000>; ++ }; ++ opp-1398000000 { ++ opp-microvolt = <800000>; ++ }; ++ opp-1512000000 { ++ opp-microvolt = <825000>; ++ }; ++ opp-1608000000 { ++ opp-microvolt = <862500>; ++ }; ++ opp-1704000000 { ++ opp-microvolt = <900000>; ++ }; ++ opp-1800000000 { ++ opp-microvolt = <987500>; ++ }; ++ opp-1908000000 { ++ opp-microvolt = <1025000>; ++ }; ++ opp-2016000000 { ++ opp-hz = /bits/ 64 <2016000000>; ++ opp-microvolt = <1025000>; ++ }; ++ opp-2100000000 { ++ opp-hz = /bits/ 64 <2100000000>; ++ opp-microvolt = <1025000>; ++ }; ++ opp-2208000000 { ++ opp-hz = /bits/ 64 <2208000000>; ++ opp-microvolt = <1050000>; ++ }; ++}; ++ ++&i2c_AO { ++ status = "okay"; ++ pinctrl-0 = <&i2c_ao_sck_pins>, <&i2c_ao_sda_pins>; ++ pinctrl-names = "default"; ++ ++ rk818: pmic@1c { ++ compatible = "rockchip,rk818"; ++ reg = <0x1c>; ++ interrupt-parent = <&gpio_intc>; ++ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; /* GPIOAO_7 */ ++ rockchip,system-power-controller; ++ clock-output-names = "rk808-clkout1", "rk808-clkout2"; ++ ++ vcc1-supply = <&vdd_sys>; ++ vcc2-supply = <&vdd_sys>; ++ vcc3-supply = <&vdd_sys>; ++ vcc4-supply = <&vdd_sys>; ++ vcc6-supply = <&vdd_sys>; ++ vcc7-supply = <&vcc_2v3>; ++ vcc8-supply = <&vcc_2v3>; ++ vcc9-supply = <&vddao_3v3>; ++ boost-supply = <&vdd_sys>; ++ switch-supply = <&vdd_sys>; ++ ++ regulators { ++ vddcpu_a: DCDC_REG1 { ++ regulator-name = "vddcpu_a"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <750000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <750000>; ++ }; ++ }; ++ ++ vdd_ee: DCDC_REG2 { ++ regulator-name = "vdd_ee"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <875000>; ++ regulator-max-microvolt = <900000>; ++ regulator-ramp-delay = <6001>; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <875000>; ++ }; ++ }; ++ ++ vddq_1v1: DCDC_REG3 { ++ regulator-name = "vddq_1v1"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ vddao_3v3: DCDC_REG4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vddao_3v3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3000000>; ++ }; ++ }; ++ ++ hp_5v: DCDC_BOOST { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-name = "hp_5v"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG1 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO1"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG2 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO2"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG3 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO3"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG4 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO4"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vddio_ao1v8: LDO_REG5 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vddio_ao1v8"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ LDO_REG6 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO6"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vddq_1v8: LDO_REG7 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vddq_1v8"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1800000>; ++ }; ++ }; ++ ++ LDO_REG8 { ++ regulator-boot-off; ++ regulator-name = "rk818_LDO8"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vddio_c: LDO_REG9 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vddio_c"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <3300000>; ++ }; ++ }; ++ ++ vcc_sd: SWITCH_REG { ++ regulator-name = "vcc_sd"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ rk818_otg_switch: OTG_SWITCH { ++ regulator-name = "otg_switch"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ ++ battery { ++ compatible = "rockchip,rk818-battery"; ++ ++ ocv_table = < ++ 3470 3599 3671 3701 3728 3746 3762 ++ 3772 3781 3792 3816 3836 3866 3910 ++ 3942 3971 4002 4050 4088 4132 4200>; ++ design_capacity = <4000>; ++ design_qmax = <4100>; ++ bat_res = <180>; ++ max_input_current = <2000>; ++ max_chrg_current = <1500>; ++ max_chrg_voltage = <4250>; ++ sleep_enter_current = <300>; ++ sleep_exit_current = <300>; ++ power_off_thresd = <3450>; ++ zero_algorithm_vol = <3700>; ++ fb_temperature = <105>; ++ sample_res = <10>; ++ max_soc_offset = <60>; ++ energy_mode = <0>; ++ monitor_sec = <5>; ++ virtual_power = <0>; ++ power_dc2otg = <0>; ++ otg5v_suspend_enable = <0>; ++ }; ++ ++ charger { ++ compatible = "rockchip,rk818-charger"; ++ monitored-battery = <&bat>; ++ }; ++ ++ }; ++}; ++ ++&i2c3 { ++ status = "okay"; ++ pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>; ++ pinctrl-names = "default"; ++ ++ rk817: pmic@20 { ++ compatible = "rockchip,rk817"; ++ reg = <0x20>; ++ status = "okay"; ++ interrupt-parent = <&gpio_intc>; ++ interrupts = <5 IRQ_TYPE_LEVEL_LOW>; /* GPIOAO_5 */ ++ wakeup-source; ++ ++ vcc1-supply = <&vdd_sys>; ++ vcc2-supply = <&vdd_sys>; ++ vcc3-supply = <&vdd_sys>; ++ vcc4-supply = <&vdd_sys>; ++ vcc5-supply = <&vdd_sys>; ++ vcc6-supply = <&vdd_sys>; ++ vcc7-supply = <&vdd_sys>; ++ vcc8-supply = <&vdd_sys>; ++ vcc9-supply = <&rk817_boost>; ++ ++ #sound-dai-cells = <0>; ++ clocks = <&codec_clk>; ++ clock-names = "mclk"; ++ ++ regulators { ++ DCDC_REG1 { ++ regulator-boot-off; ++ regulator-name = "rk817_BUCK1"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vddcpu_b: DCDC_REG2 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <725000>; ++ regulator-max-microvolt = <1050000>; ++ regulator-ramp-delay = <6001>; ++ regulator-initial-mode = <0x2>; ++ regulator-name = "vddcpu_b"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1000000>; ++ }; ++ }; ++ ++ vcc_2v3: DCDC_REG3 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <2300000>; ++ regulator-max-microvolt = <2400000>; ++ regulator-initial-mode = <0x2>; ++ regulator-name = "vcc_2v3"; ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ }; ++ }; ++ ++ DCDC_REG4 { ++ regulator-boot-off; ++ regulator-name = "rk817_BUCK4"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG1 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO1"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG2 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO2"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG3 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO3"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG4 { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vdd_codec"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG5 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO5"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG6 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO6"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG7 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO7"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vcc_lcd: LDO_REG8 { ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-name = "vcc_lcd"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ LDO_REG9 { ++ regulator-boot-off; ++ regulator-name = "rk817_LDO9"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ rk817_boost: BOOST { ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5400000>; ++ regulator-name = "rk817_boost"; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ usb_host: OTG_SWITCH { ++ regulator-name = "usb_host"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ ++ rk817_codec: codec { ++ rockchip,mic-in-differential; ++ }; ++ }; ++}; ++ ++&clkc_audio { ++ status = "okay"; ++}; ++ ++ð_phy { ++ status = "disabled"; ++}; ++ ++&frddr_a { ++ status = "okay"; ++}; ++ ++&frddr_b { ++ status = "okay"; ++}; ++ ++&frddr_c { ++ status = "okay"; ++}; ++ ++&toddr_a { ++ status = "okay"; ++}; ++ ++&toddr_b { ++ status = "okay"; ++}; ++ ++&toddr_c { ++ status = "okay"; ++}; ++ ++&mipi_dsi { ++ status = "okay"; ++ ++ assigned-clocks = <&clkc CLKID_GP0_PLL>, ++ <&clkc CLKID_MIPI_DSI_PXCLK_SEL>, ++ <&clkc CLKID_MIPI_DSI_PXCLK>, ++ <&clkc CLKID_CTS_ENCL_SEL>, ++ <&clkc CLKID_VCLK2_SEL>; ++ assigned-clock-parents = <0>, ++ <&clkc CLKID_GP0_PLL>, ++ <0>, ++ <&clkc CLKID_VCLK2_DIV1>, ++ <&clkc CLKID_GP0_PLL>; ++ assigned-clock-rates = <344976000>, ++ <0>, ++ <344976000>, ++ <0>, ++ <0>; ++ ++ panel@0 { ++ compatible = "elida,kd50t048a", "sitronix,st7701"; ++ reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_HIGH>; ++ IOVCC-supply = <&vcc_lcd>; ++ VCC-supply = <&vcc_lcd>; ++ backlight = <&panel_backlight>; ++ rotation = <270>; ++ reg = <0>; ++ ++ port { ++ mipi_in_panel: endpoint { ++ remote-endpoint = <&mipi_out_panel>; ++ }; ++ }; ++ }; ++}; ++ ++&mipi_analog_dphy { ++ status = "okay"; ++}; ++ ++&mipi_dphy { ++ status = "okay"; ++}; ++ ++&mipi_dsi_panel_port { ++ mipi_out_panel: endpoint { ++ remote-endpoint = <&mipi_in_panel>; ++ }; ++}; ++ ++&periphs_pinctrl { ++ keypad_gpio_pins: keypad-gpio { ++ mux { ++ groups = "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", ++ "GPIOX_4", "GPIOX_5", "GPIOX_6", "GPIOX_7", ++ "GPIOX_8", "GPIOX_9", "GPIOX_10", "GPIOX_11", ++ "GPIOX_12", "GPIOX_13", "GPIOX_14", "GPIOX_15", ++ "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19"; ++ function = "gpio_periphs"; ++ bias-pull-up; ++ output-disable; ++ }; ++ }; ++}; ++ ++&pwm_ef { ++ status = "okay"; ++ pinctrl-0 = <&pwm_f_h_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&saradc { ++ status = "okay"; ++ vref-supply = <&vddio_ao1v8>; ++}; ++ ++/* SD card */ ++&sd_emmc_b { ++ status = "okay"; ++ pinctrl-0 = <&sdcard_c_pins>; ++ pinctrl-1 = <&sdcard_clk_gate_c_pins>; ++ pinctrl-names = "default", "clk-gate"; ++ ++ bus-width = <4>; ++ cap-sd-highspeed; ++ max-frequency = <50000000>; ++ disable-wp; ++ ++ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vddio_c>; ++ ++}; ++ ++/* eMMC */ ++&sd_emmc_c { ++ status = "okay"; ++ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; ++ pinctrl-1 = <&emmc_clk_gate_pins>; ++ pinctrl-names = "default", "clk-gate"; ++ ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-ddr-1_8v; ++ mmc-hs200-1_8v; ++ max-frequency = <200000000>; ++ disable-wp; ++ ++ mmc-pwrseq = <&emmc_pwrseq>; ++ vmmc-supply = <&vcc_sd>; ++ vqmmc-supply = <&vddio_ao1v8>; ++}; ++ ++ ++&tdmif_b { ++ pinctrl-0 = <&mclk0_a_pins>, <&tdm_b_fs_pins>, <&tdm_b_sclk_pins>, ++ <&tdm_b_dout0_pins>; ++ pinctrl-names = "default"; ++ status = "okay"; ++ ++ assigned-clocks = <&clkc_audio AUD_CLKID_TDM_MCLK_PAD0>, ++ <&clkc_audio AUD_CLKID_TDM_SCLK_PAD1>, ++ <&clkc_audio AUD_CLKID_TDM_LRCLK_PAD1>; ++ assigned-clock-parents = <&clkc_audio AUD_CLKID_MST_B_MCLK>, ++ <&clkc_audio AUD_CLKID_MST_B_SCLK>, ++ <&clkc_audio AUD_CLKID_MST_B_LRCLK>; ++ assigned-clock-rates = <0>, <0>, <0>; ++}; ++ ++&tdmout_b { ++ status = "okay"; ++}; ++ ++&uart_AO { ++ status = "okay"; ++ pinctrl-0 = <&uart_ao_a_pins>; ++ pinctrl-names = "default"; ++}; ++ ++&usb { ++ status = "okay"; ++ dr_mode = "peripheral"; ++}; ++ ++&usb2_phy0 { ++ status = "okay"; ++}; ++ ++&usb2_phy1 { ++ status = "okay"; ++ phy-supply = <&usb_host>; ++}; diff --git a/projects/Amlogic/packages/linux/patches/S922X/001-mali-gpu-r44.patch b/projects/Amlogic/packages/linux/patches/S922X/002.01-Add-Mali-GPU-r44-driver.patch similarity index 100% rename from projects/Amlogic/packages/linux/patches/S922X/001-mali-gpu-r44.patch rename to projects/Amlogic/packages/linux/patches/S922X/002.01-Add-Mali-GPU-r44-driver.patch diff --git a/projects/Amlogic/packages/linux/patches/S922X/002.02-Add-Mali-to-device-trees.patch b/projects/Amlogic/packages/linux/patches/S922X/002.02-Add-Mali-to-device-trees.patch new file mode 100644 index 000000000..9746ea302 --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/002.02-Add-Mali-to-device-trees.patch @@ -0,0 +1,40 @@ +diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +--- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi 2023-09-12 12:02:56.937601871 +0000 ++++ linux/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi 2023-09-12 12:03:27.490291628 +0000 +@@ -2394,14 +2391,20 @@ + }; + + mali: gpu@ffe40000 { +- compatible = "amlogic,meson-g12a-mali", "arm,mali-bifrost"; +- reg = <0x0 0xffe40000 0x0 0x40000>; ++ compatible = "arm,mali-midgard"; ++ reg = <0x0 0xffe40000 0x0 0x40000>, ++ <0 0xFFD01000 0 0x01000>, ++ <0 0xFF800000 0 0x01000>, ++ <0 0xFF63c000 0 0x01000>, ++ <0 0xFFD01000 0 0x01000>; ++ + interrupt-parent = <&gic>; +- interrupts = , ++ interrupts = , + , +- ; +- interrupt-names = "job", "mmu", "gpu"; ++ ; ++ interrupt-names = "GPU", "MMU", "JOB"; + clocks = <&clkc CLKID_MALI>; ++ clock-names = "clk_mali"; + resets = <&reset RESET_DVALIN_CAPB3>, <&reset RESET_DVALIN>; + operating-points-v2 = <&gpu_opp_table>; + #cooling-cells = <2>; +diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi +--- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi 2023-09-12 12:02:56.937601871 +0000 ++++ linux/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi 2023-09-12 12:03:27.490291628 +0000 +@@ -137,5 +139,6 @@ + }; + + &mali { +- dma-coherent; ++ system-coherency = <0>; ++ power_policy = "always_on"; + }; diff --git a/projects/Amlogic/packages/linux/patches/S922X/003.01-ODROID-N2-heartbeat-quirk.patch b/projects/Amlogic/packages/linux/patches/S922X/003.01-ODROID-N2-heartbeat-quirk.patch new file mode 100644 index 000000000..fe818752f --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/003.01-ODROID-N2-heartbeat-quirk.patch @@ -0,0 +1,11 @@ +--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi +@@ -45,7 +45,7 @@ + led-blue { + label = "n2:blue"; + gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "heartbeat"; ++ linux,default-trigger = "none"; + }; + }; + diff --git a/projects/Amlogic/packages/linux/patches/S922X/003.02-DRM-panel-orientation-quirk.patch b/projects/Amlogic/packages/linux/patches/S922X/003.02-DRM-panel-orientation-quirk.patch new file mode 100644 index 000000000..e8bedbe1c --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/003.02-DRM-panel-orientation-quirk.patch @@ -0,0 +1,12 @@ +diff -rupN linux.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c linux/drivers/gpu/drm/drm_panel_orientation_quirks.c +--- linux.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-09-12 12:02:57.953624819 +0000 ++++ linux/drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-09-12 12:03:27.490291628 +0000 +@@ -477,7 +477,7 @@ EXPORT_SYMBOL(drm_get_panel_orientation_ + /* There are no quirks for non x86 devices yet */ + int drm_get_panel_orientation_quirk(int width, int height) + { +- return DRM_MODE_PANEL_ORIENTATION_UNKNOWN; ++ return DRM_MODE_PANEL_ORIENTATION_LEFT_UP; + } + EXPORT_SYMBOL(drm_get_panel_orientation_quirk); + diff --git a/projects/Amlogic/packages/linux/patches/S922X/004.01-ODROID-GO-Ultra-joypad-driver.patch b/projects/Amlogic/packages/linux/patches/S922X/004.01-ODROID-GO-Ultra-joypad-driver.patch new file mode 100644 index 000000000..8f68ef873 --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/004.01-ODROID-GO-Ultra-joypad-driver.patch @@ -0,0 +1,1028 @@ +diff -rupN linux.orig/drivers/input/joystick/Kconfig linux/drivers/input/joystick/Kconfig +--- linux.orig/drivers/input/joystick/Kconfig 2023-09-12 12:02:58.173629790 +0000 ++++ linux/drivers/input/joystick/Kconfig 2023-09-12 12:03:27.490291628 +0000 +@@ -344,6 +344,12 @@ config JOYSTICK_MAPLE + To compile this as a module choose M here: the module will be called + maplecontrol. + ++config JOYSTICK_ODROID_GOU ++ tristate "ODROID-Go-Ultra joypad driver" ++ depends on INPUT_POLLDEV ++ help ++ Made for ODROID-GO-Ultra. ++ + config JOYSTICK_PSXPAD_SPI + tristate "PlayStation 1/2 joypads via SPI interface" + depends on SPI +diff -rupN linux.orig/drivers/input/joystick/Makefile linux/drivers/input/joystick/Makefile +--- linux.orig/drivers/input/joystick/Makefile 2023-09-12 12:02:58.173629790 +0000 ++++ linux/drivers/input/joystick/Makefile 2023-09-12 12:03:27.490291628 +0000 +@@ -25,6 +25,7 @@ obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydu + obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o + obj-$(CONFIG_JOYSTICK_MAPLE) += maplecontrol.o + obj-$(CONFIG_JOYSTICK_N64) += n64joy.o ++obj-$(CONFIG_JOYSTICK_ODROID_GOU) += odroid-gou-joypad.o + obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o + obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o + obj-$(CONFIG_JOYSTICK_QWIIC) += qwiic-joystick.o +diff -rupN linux.orig/drivers/input/joystick/amlogic-saradc.h linux/drivers/input/joystick/amlogic-saradc.h +--- linux.orig/drivers/input/joystick/amlogic-saradc.h 1970-01-01 00:00:00.000000000 +0000 ++++ linux/drivers/input/joystick/amlogic-saradc.h 2023-09-12 12:03:27.490291628 +0000 +@@ -0,0 +1,32 @@ ++/* ++ * include/dt-bindings/iio/adc/amlogic-saradc.h ++ * ++ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ */ ++ ++#ifndef _DT_BINDINGS_IIO_ADC_AMLOGIC_H ++#define _DT_BINDINGS_IIO_ADC_AMLOGIC_H ++ ++#define SARADC_CH0 0 ++#define SARADC_CH1 1 ++#define SARADC_CH2 2 ++#define SARADC_CH3 3 ++#define SARADC_CH4 4 ++#define SARADC_CH5 5 ++#define SARADC_CH6 6 ++#define SARADC_CH7 7 ++ ++#define SARADC_CH_NUM 8 ++ ++#endif +diff -rupN linux.orig/drivers/input/joystick/odroid-gou-joypad.c linux/drivers/input/joystick/odroid-gou-joypad.c +--- linux.orig/drivers/input/joystick/odroid-gou-joypad.c 1970-01-01 00:00:00.000000000 +0000 ++++ linux/drivers/input/joystick/odroid-gou-joypad.c 2023-09-12 12:03:27.490291628 +0000 +@@ -0,0 +1,960 @@ ++/*----------------------------------------------------------------------------*/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "amlogic-saradc.h" ++#include ++ ++/*----------------------------------------------------------------------------*/ ++#define DRV_NAME "odroidgo_joypad" ++ ++/*----------------------------------------------------------------------------*/ ++ ++ ++/*----------------------------------------------------------------------------*/ ++#define ADC_MAX_VOLTAGE 1800 ++#define ADC_DATA_TUNING(x, p) ((x * p) / 100) ++#define ADC_TUNING_DEFAULT 180 ++ ++struct bt_adc { ++ /* report value (mV) */ ++ int value; ++ /* report type */ ++ int report_type; ++ /* input device init value (mV) */ ++ int max, min; ++ /* calibrated adc value */ ++ int cal; ++ /* adc scale value */ ++ int scale; ++ /* invert report */ ++ bool invert; ++ /* adc channel */ ++ int channel; ++ /* adc data tuning value([percent), p = positive, n = negative */ ++ int tuning_p, tuning_n; ++}; ++ ++struct bt_gpio { ++ /* GPIO Request label */ ++ const char *label; ++ /* GPIO Number */ ++ int num; ++ /* report type */ ++ int report_type; ++ /* report linux code */ ++ int linux_code; ++ /* prev button value */ ++ bool old_value; ++ /* button press level */ ++ bool active_level; ++}; ++ ++struct joypad { ++ struct device *dev; ++ struct input_polled_dev *poll_dev; ++ int poll_interval; ++ ++ /* report enable/disable */ ++ bool enable; ++ ++ /* analog mux & joystick control */ ++ struct iio_channel *adc_ch[SARADC_CH_NUM]; ++ ++ /* adc input channel count */ ++ int chan_count; ++ /* analog button */ ++ struct bt_adc *adcs; ++ ++ /* report interval (ms) */ ++ int bt_gpio_count; ++ struct bt_gpio *gpios; ++ ++ /* button auto repeat */ ++ int auto_repeat; ++ ++ /* report threshold (mV) */ ++ int bt_adc_fuzz, bt_adc_flat; ++ /* adc read value scale */ ++ int bt_adc_scale; ++ /* joystick deadzone control */ ++ int bt_adc_deadzone; ++ ++ struct mutex lock; ++ ++ /* adc debug channel */ ++ int debug_ch; ++}; ++ ++/*----------------------------------------------------------------------------*/ ++// ++// set to the value in the boot.ini file. (if exist) ++// ++/*----------------------------------------------------------------------------*/ ++static unsigned int g_button_adc_fuzz = 0; ++static unsigned int g_button_adc_flat = 0; ++static unsigned int g_button_adc_scale = 0; ++static unsigned int g_button_adc_deadzone = 0; ++ ++static int button_adc_fuzz(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_fuzz = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-fuzz=", button_adc_fuzz); ++ ++static int button_adc_flat(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_flat = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-flat=", button_adc_flat); ++ ++static int button_adc_scale(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_scale = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-scale=", button_adc_scale); ++ ++static int button_adc_deadzone(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ g_button_adc_deadzone = simple_strtoul(str, NULL, 10); ++ return 0; ++} ++__setup("button-adc-deadzone=", button_adc_deadzone); ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_read(struct joypad *joypad, struct bt_adc *adc) ++{ ++ int value; ++ ++ if (iio_read_channel_processed(joypad->adc_ch[adc->channel], &value) < 0) ++ return 0; ++ ++ value *= adc->scale; ++ ++ return (adc->invert ? (adc->max - value) : value); ++} ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo_joypad/poll_interval [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->poll_interval = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_poll_interval(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->poll_interval); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(poll_interval, S_IWUSR | S_IRUGO, ++ joypad_show_poll_interval, ++ joypad_store_poll_interval); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo_joypad/adc_fuzz [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_fuzz(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_fuzz); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_fuzz, S_IWUSR | S_IRUGO, ++ joypad_show_adc_fuzz, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo_joypad/adc_flat [r] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_flat(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->bt_adc_flat); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_flat, S_IWUSR | S_IRUGO, ++ joypad_show_adc_flat, ++ NULL); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/oodroidgo_joypad/enable [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_enable(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ mutex_lock(&joypad->lock); ++ joypad->enable = simple_strtoul(buf, NULL, 10); ++ mutex_unlock(&joypad->lock); ++ ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_enable(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", joypad->enable); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, ++ joypad_show_enable, ++ joypad_store_enable); ++ ++/*----------------------------------------------------------------------------*/ ++/* ++ * ATTRIBUTES: ++ * ++ * /sys/devices/platform/odroidgo_joypad/adc_cal [rw] ++ */ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_store_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, ++ size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ bool calibration; ++ ++ calibration = simple_strtoul(buf, NULL, 10); ++ ++ if (calibration) { ++ int nbtn; ++ ++ mutex_lock(&joypad->lock); ++ for (nbtn = 0; nbtn < joypad->chan_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->value; ++ } ++ mutex_unlock(&joypad->lock); ++ } ++ return count; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static ssize_t joypad_show_adc_cal(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ int nbtn; ++ ssize_t pos; ++ ++ for (nbtn = 0, pos = 0; nbtn < joypad->chan_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ pos += sprintf(&buf[pos], "adc[%d]->cal = %d\n", ++ nbtn, adc->cal); ++ } ++ pos += sprintf(&buf[pos], "adc scale = %d\n", joypad->bt_adc_scale); ++ return pos; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static DEVICE_ATTR(adc_cal, S_IWUSR | S_IRUGO, ++ joypad_show_adc_cal, ++ joypad_store_adc_cal); ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static struct attribute *joypad_attrs[] = { ++ &dev_attr_poll_interval.attr, ++ &dev_attr_adc_fuzz.attr, ++ &dev_attr_adc_flat.attr, ++ &dev_attr_enable.attr, ++ &dev_attr_adc_cal.attr, ++ NULL, ++}; ++ ++static struct attribute_group joypad_attr_group = { ++ .attrs = joypad_attrs, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++/*----------------------------------------------------------------------------*/ ++static void joypad_gpio_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn, value; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ ++ if (gpio_get_value_cansleep(gpio->num) < 0) { ++ dev_err(joypad->dev, "failed to get gpio state\n"); ++ continue; ++ } ++ value = gpio_get_value(gpio->num); ++ if (value != gpio->old_value) { ++ input_event(poll_dev->input, ++ gpio->report_type, ++ gpio->linux_code, ++ (value == gpio->active_level) ? 1 : 0); ++ gpio->old_value = value; ++ } ++ } ++ input_sync(poll_dev->input); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_adc_check(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ int mag; ++ ++ /* Assumes an even number of axes and that joystick axis pairs are sequential */ ++ /* e.g. left stick Y immediately follows left stick X */ ++ for (nbtn = 0; nbtn < joypad->chan_count; nbtn += 2) { ++ struct bt_adc *adcx = &joypad->adcs[nbtn]; ++ struct bt_adc *adcy = &joypad->adcs[nbtn + 1]; ++ ++ /* Read first joystick axis */ ++ adcx->value = joypad_adc_read(joypad, adcx); ++ if (!adcx->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adcx->value = adcx->value - adcx->cal; ++ ++ /* Read second joystick axis */ ++ adcy->value = joypad_adc_read(joypad, adcy); ++ if (!adcy->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn + 1); ++ continue; ++ } ++ adcy->value = adcy->value - adcy->cal; ++ ++ /* Scaled Radial Deadzone */ ++ /* https://web.archive.org/web/20190129113357/http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html */ ++ mag = int_sqrt((adcx->value * adcx->value) + (adcy->value * adcy->value)); ++ if (joypad->bt_adc_deadzone) { ++ if (mag <= joypad->bt_adc_deadzone) { ++ adcx->value = 0; ++ adcy->value = 0; ++ } ++ else { ++ /* Assumes adcx->max == -adcx->min == adcy->max == -adcy->min */ ++ /* Order of operations is critical to avoid integer overflow */ ++ adcx->value = (((adcx->max * adcx->value) / mag) * (mag - joypad->bt_adc_deadzone)) / (adcx->max - joypad->bt_adc_deadzone); ++ adcy->value = (((adcy->max * adcy->value) / mag) * (mag - joypad->bt_adc_deadzone)) / (adcy->max - joypad->bt_adc_deadzone); ++ } ++ } ++ ++ /* adc data tuning */ ++ if (adcx->tuning_n && adcx->value < 0) ++ adcx->value = ADC_DATA_TUNING(adcx->value, adcx->tuning_n); ++ if (adcx->tuning_p && adcx->value > 0) ++ adcx->value = ADC_DATA_TUNING(adcx->value, adcx->tuning_p); ++ if (adcy->tuning_n && adcy->value < 0) ++ adcy->value = ADC_DATA_TUNING(adcy->value, adcy->tuning_n); ++ if (adcy->tuning_p && adcy->value > 0) ++ adcy->value = ADC_DATA_TUNING(adcy->value, adcy->tuning_p); ++ ++ /* Clamp to [min, max] */ ++ adcx->value = adcx->value > adcx->max ? adcx->max : adcx->value; ++ adcx->value = adcx->value < adcx->min ? adcx->min : adcx->value; ++ adcy->value = adcy->value > adcy->max ? adcy->max : adcy->value; ++ adcy->value = adcy->value < adcy->min ? adcy->min : adcy->value; ++ ++ input_report_abs(poll_dev->input, ++ adcx->report_type, ++ adcx->invert ? adcx->value * (-1) : adcx->value); ++ input_report_abs(poll_dev->input, ++ adcy->report_type, ++ adcy->invert ? adcy->value * (-1) : adcy->value); ++ } ++ input_sync(poll_dev->input); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_poll(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ if (joypad->enable) { ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ } ++ if (poll_dev->poll_interval != joypad->poll_interval) { ++ mutex_lock(&joypad->lock); ++ poll_dev->poll_interval = joypad->poll_interval; ++ mutex_unlock(&joypad->lock); ++ } ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_open(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ int nbtn; ++ ++ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ gpio->old_value = gpio->active_level ? 0 : 1; ++ } ++ for (nbtn = 0; nbtn < joypad->chan_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->value = joypad_adc_read(joypad, adc); ++ if (!adc->value) { ++ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", ++ __func__, nbtn); ++ continue; ++ } ++ adc->cal = adc->value; ++ dev_info(joypad->dev, "%s : adc[%d] adc->cal = %d\n", ++ __func__, nbtn, adc->cal); ++ } ++ /* buttons status sync */ ++ joypad_adc_check(poll_dev); ++ joypad_gpio_check(poll_dev); ++ ++ /* button report enable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = true; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : opened\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_close(struct input_polled_dev *poll_dev) ++{ ++ struct joypad *joypad = poll_dev->private; ++ ++ /* button report disable */ ++ mutex_lock(&joypad->lock); ++ joypad->enable = false; ++ mutex_unlock(&joypad->lock); ++ ++ dev_info(joypad->dev, "%s : closed\n", __func__); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_iochannel_setup(struct device *dev, struct joypad *joypad) ++{ ++ enum iio_chan_type type; ++ unsigned char cnt; ++ const char *uname; ++ int ret; ++ ++ for (cnt = 0; cnt < joypad->chan_count; cnt++) { ++ ++ ret = of_property_read_string_index(dev->of_node, ++ "io-channel-names", cnt, &uname); ++ if (ret < 0) { ++ dev_err(dev, "invalid channel name index[%d]\n", cnt); ++ return -EINVAL; ++ } ++ ++ joypad->adc_ch[cnt] = devm_iio_channel_get(dev, ++ uname); ++ if (IS_ERR(joypad->adc_ch[cnt])) { ++ dev_err(dev, "iio channel get error\n"); ++ return -EINVAL; ++ } ++ if (!joypad->adc_ch[cnt]->indio_dev) ++ return -ENXIO; ++ ++ if (iio_get_channel_type(joypad->adc_ch[cnt], &type)) ++ return -EINVAL; ++ ++ if (type != IIO_VOLTAGE) { ++ dev_err(dev, "Incompatible channel type %d\n", type); ++ return -EINVAL; ++ } ++ } ++ return ret; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_adc_setup(struct device *dev, struct joypad *joypad) ++{ ++ int nbtn; ++ ++ /* adc button struct init */ ++ joypad->adcs = devm_kzalloc(dev, joypad->chan_count * ++ sizeof(struct bt_adc), GFP_KERNEL); ++ if (!joypad->adcs) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ for (nbtn = 0; nbtn < joypad->chan_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ ++ adc->scale = joypad->bt_adc_scale; ++ ++ adc->max = (ADC_MAX_VOLTAGE / 2); ++ adc->min = (ADC_MAX_VOLTAGE / 2) * (-1); ++ if (adc->scale) { ++ adc->max *= adc->scale; ++ adc->min *= adc->scale; ++ } ++ adc->channel = nbtn; ++ adc->invert = false; ++ ++ switch (nbtn) { ++ case 0: ++ adc->report_type = ABS_RY; ++ if (device_property_read_u32(dev, ++ "abs_ry-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_ry-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 1: ++ adc->report_type = ABS_RX; ++ if (device_property_read_u32(dev, ++ "abs_rx-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_rx-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 2: ++ adc->report_type = ABS_Y; ++ if (device_property_read_u32(dev, ++ "abs_y-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_y-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ case 3: ++ adc->report_type = ABS_X; ++ if (device_property_read_u32(dev, ++ "abs_x-p-tuning", ++ &adc->tuning_p)) ++ adc->tuning_p = ADC_TUNING_DEFAULT; ++ if (device_property_read_u32(dev, ++ "abs_x-n-tuning", ++ &adc->tuning_n)) ++ adc->tuning_n = ADC_TUNING_DEFAULT; ++ break; ++ default : ++ dev_err(dev, "%s io channel count(%d) error!", ++ __func__, nbtn); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_gpio_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct device_node *node, *pp; ++ int nbtn; ++ ++ node = dev->of_node; ++ if (!node) ++ return -ENODEV; ++ ++ joypad->gpios = devm_kzalloc(dev, joypad->bt_gpio_count * ++ sizeof(struct bt_gpio), GFP_KERNEL); ++ ++ if (!joypad->gpios) { ++ dev_err(dev, "%s devm_kzmalloc error!", __func__); ++ return -ENOMEM; ++ } ++ ++ nbtn = 0; ++ for_each_child_of_node(node, pp) { ++ enum of_gpio_flags flags; ++ struct bt_gpio *gpio = &joypad->gpios[nbtn++]; ++ int error; ++ ++ gpio->num = of_get_gpio_flags(pp, 0, &flags); ++ if (gpio->num < 0) { ++ error = gpio->num; ++ dev_err(dev, "Failed to get gpio flags, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* gpio active level(key press level) */ ++ gpio->active_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; ++ ++ gpio->label = of_get_property(pp, "label", NULL); ++ ++ if (gpio_is_valid(gpio->num)) { ++ error = devm_gpio_request_one(dev, gpio->num, ++ GPIOF_IN, gpio->label); ++ if (error < 0) { ++ dev_err(dev, ++ "Failed to request GPIO %d, error %d\n", ++ gpio->num, error); ++ return error; ++ } ++ #if 0 ++ error = gpiod_set_pull(gpio_to_desc(gpio->num), GPIOD_PULL_UP); ++ if (error < 0) { ++ dev_err(dev, ++ "Failed to set pull-up GPIO %d, error %d\n", ++ gpio->num, error); ++ return error; ++ } ++ #endif ++ } ++ if (of_property_read_u32(pp, "linux,code", &gpio->linux_code)) { ++ dev_err(dev, "Button without keycode: 0x%x\n", ++ gpio->num); ++ return -EINVAL; ++ } ++ if (of_property_read_u32(pp, "linux,input-type", ++ &gpio->report_type)) ++ gpio->report_type = EV_KEY; ++ } ++ if (nbtn == 0) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_input_setup(struct device *dev, struct joypad *joypad) ++{ ++ struct input_polled_dev *poll_dev; ++ struct input_dev *input; ++ int nbtn, error; ++ u32 joypad_vendor = 0; ++ u32 joypad_revision = 0; ++ u32 joypad_product = 0; ++ ++ poll_dev = devm_input_allocate_polled_device(dev); ++ if (!poll_dev) { ++ dev_err(dev, "no memory for polled device\n"); ++ return -ENOMEM; ++ } ++ ++ poll_dev->private = joypad; ++ poll_dev->poll = joypad_poll; ++ poll_dev->poll_interval = joypad->poll_interval; ++ poll_dev->open = joypad_open; ++ poll_dev->close = joypad_close; ++ ++ input = poll_dev->input; ++ ++ input->name = DRV_NAME; ++ ++ device_property_read_string(dev, "joypad-name", &input->name); ++ input->phys = DRV_NAME"/input0"; ++ ++ device_property_read_u32(dev, "joypad-vendor", &joypad_vendor); ++ device_property_read_u32(dev, "joypad-revision", &joypad_revision); ++ device_property_read_u32(dev, "joypad-product", &joypad_product); ++ //input->id.bustype = BUS_HOST; ++ input->id.bustype = BUS_USB; ++ input->id.vendor = (u16)joypad_vendor; ++ input->id.product = (u16)joypad_product; ++ input->id.version = (u16)joypad_revision; ++ ++ /* IIO ADC key setup (0 mv ~ 1800 mv) * adc->scale */ ++ __set_bit(EV_ABS, input->evbit); ++ ++ // Set mapped ones on dt ++ for(nbtn = 0; nbtn < joypad->chan_count; nbtn++) { ++ struct bt_adc *adc = &joypad->adcs[nbtn]; ++ input_set_abs_params(input, adc->report_type, ++ adc->min, adc->max, ++ joypad->bt_adc_fuzz, ++ joypad->bt_adc_flat); ++ dev_info(dev, ++ "%s : SCALE = %d, ABS min = %d, max = %d," ++ " fuzz = %d, flat = %d, deadzone = %d\n", ++ __func__, adc->scale, adc->min, adc->max, ++ joypad->bt_adc_fuzz, joypad->bt_adc_flat, ++ joypad->bt_adc_deadzone); ++ dev_info(dev, ++ "%s : adc tuning_p = %d, adc_tuning_n = %d\n\n", ++ __func__, adc->tuning_p, adc->tuning_n); ++ } ++ ++ /* GPIO key setup */ ++ __set_bit(EV_KEY, input->evbit); ++ for(nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { ++ struct bt_gpio *gpio = &joypad->gpios[nbtn]; ++ input_set_capability(input, gpio->report_type, ++ gpio->linux_code); ++ } ++ ++ if (joypad->auto_repeat) ++ __set_bit(EV_REP, input->evbit); ++ ++ joypad->dev = dev; ++ ++ error = input_register_polled_device(poll_dev); ++ if (error) { ++ dev_err(dev, "unable to register polled device, err=%d\n", ++ error); ++ return error; ++ } ++ joypad->dev = dev; ++ joypad->poll_dev = poll_dev; ++ ++ return 0; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void joypad_setup_value_check(struct device *dev, struct joypad *joypad) ++{ ++ /* ++ fuzz: specifies fuzz value that is used to filter noise from ++ the event stream. ++ */ ++ if (g_button_adc_fuzz) ++ joypad->bt_adc_fuzz = g_button_adc_fuzz; ++ else ++ device_property_read_u32(dev, "button-adc-fuzz", ++ &joypad->bt_adc_fuzz); ++ /* ++ flat: values that are within this value will be discarded by ++ joydev interface and reported as 0 instead. ++ */ ++ if (g_button_adc_flat) ++ joypad->bt_adc_flat = g_button_adc_flat; ++ else ++ device_property_read_u32(dev, "button-adc-flat", ++ &joypad->bt_adc_flat); ++ ++ /* Joystick report value control */ ++ if (g_button_adc_scale) ++ joypad->bt_adc_scale = g_button_adc_scale; ++ else ++ device_property_read_u32(dev, "button-adc-scale", ++ &joypad->bt_adc_scale); ++ ++ /* Joystick deadzone value control */ ++ if (g_button_adc_deadzone) ++ joypad->bt_adc_deadzone = g_button_adc_deadzone; ++ else ++ device_property_read_u32(dev, "button-adc-deadzone", ++ &joypad->bt_adc_deadzone); ++ ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_dt_parse(struct device *dev, struct joypad *joypad) ++{ ++ int error = 0; ++ ++ /* initialize value check from boot.ini */ ++ joypad_setup_value_check(dev, joypad); ++ ++ joypad->chan_count = of_property_count_strings(dev->of_node, ++ "io-channel-names"); ++ ++ device_property_read_u32(dev, "poll-interval", ++ &joypad->poll_interval); ++ ++ joypad->auto_repeat = device_property_present(dev, "autorepeat"); ++ ++ joypad->bt_gpio_count = device_get_child_node_count(dev); ++ ++ if ((joypad->chan_count == 0) || (joypad->bt_gpio_count == 0)) { ++ dev_err(dev, "adc key = %d, gpio key = %d error!", ++ joypad->chan_count, joypad->bt_gpio_count); ++ return -EINVAL; ++ } ++ ++ error = joypad_adc_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_iochannel_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ error = joypad_gpio_setup(dev, joypad); ++ if (error) ++ return error; ++ ++ dev_info(dev, "%s : adc key cnt = %d, gpio key cnt = %d\n", ++ __func__, joypad->chan_count, joypad->bt_gpio_count); ++ ++ return error; ++} ++ ++/*----------------------------------------------------------------------------*/ ++static int joypad_probe(struct platform_device *pdev) ++{ ++ struct joypad *joypad; ++ struct device *dev = &pdev->dev; ++ int error; ++ ++ joypad = devm_kzalloc(dev, sizeof(struct joypad), GFP_KERNEL); ++ if (!joypad) { ++ dev_err(dev, "joypad devm_kzmalloc error!"); ++ return -ENOMEM; ++ } ++ ++ /* device tree data parse */ ++ error = joypad_dt_parse(dev, joypad); ++ if (error) { ++ dev_err(dev, "dt parse error!(err = %d)\n", error); ++ return error; ++ } ++ ++ mutex_init(&joypad->lock); ++ platform_set_drvdata(pdev, joypad); ++ ++ error = sysfs_create_group(&pdev->dev.kobj, &joypad_attr_group); ++ if (error) { ++ dev_err(dev, "create sysfs group fail, error: %d\n", ++ error); ++ return error; ++ } ++ ++ /* poll input device setup */ ++ error = joypad_input_setup(dev, joypad); ++ if (error) { ++ dev_err(dev, "input setup failed!(err = %d)\n", error); ++ return error; ++ } ++ dev_info(dev, "%s : probe success\n", __func__); ++ return 0; ++} ++ ++static void joypad_shutdown(struct platform_device *pdev) ++{ ++ struct joypad *joypad = platform_get_drvdata(pdev); ++ input_unregister_polled_device(joypad->poll_dev); ++} ++/*----------------------------------------------------------------------------*/ ++static const struct of_device_id joypad_of_match[] = { ++ { .compatible = "odroidgou-joypad", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, joypad_of_match); ++ ++/*----------------------------------------------------------------------------*/ ++static struct platform_driver joypad_driver = { ++ .probe = joypad_probe, ++ .shutdown = joypad_shutdown, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = of_match_ptr(joypad_of_match), ++ }, ++}; ++ ++/*----------------------------------------------------------------------------*/ ++static int __init joypad_init(void) ++{ ++ return platform_driver_register(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++static void __exit joypad_exit(void) ++{ ++ platform_driver_unregister(&joypad_driver); ++} ++ ++/*----------------------------------------------------------------------------*/ ++late_initcall(joypad_init); ++module_exit(joypad_exit); ++ ++/*----------------------------------------------------------------------------*/ ++MODULE_AUTHOR("Hardkernel Co.,LTD"); ++MODULE_DESCRIPTION("Keypad driver(ADC&GPIO) for ODROIDGO-Advance"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRV_NAME); ++ ++/*----------------------------------------------------------------------------*/ + diff --git a/projects/Amlogic/packages/linux/patches/S922X/004.02-ODROID-GO-Ultra-power-off-driver.patch b/projects/Amlogic/packages/linux/patches/S922X/004.02-ODROID-GO-Ultra-power-off-driver.patch new file mode 100644 index 000000000..ce44b8368 --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/004.02-ODROID-GO-Ultra-power-off-driver.patch @@ -0,0 +1,210 @@ +diff -rupN linux.orig/drivers/power/reset/Kconfig linux/drivers/power/reset/Kconfig +--- linux.orig/drivers/power/reset/Kconfig 2023-09-12 12:02:58.741642619 +0000 ++++ linux/drivers/power/reset/Kconfig 2023-09-12 12:03:27.490291628 +0000 +@@ -141,6 +141,13 @@ config POWER_RESET_OCELOT_RESET + help + This driver supports restart for Microsemi Ocelot SoC and similar. + ++config POWER_RESET_ODROID_GO_ULTRA_POWEROFF ++ bool "Odroid Go Ultra power-off driver" ++ depends on ARCH_MESON || COMPILE_TEST ++ depends on I2C=y && OF ++ help ++ This driver supports Power off for Odroid Go Ultra device. ++ + config POWER_RESET_OXNAS + bool "OXNAS SoC restart driver" + depends on ARCH_OXNAS +diff -rupN linux.orig/drivers/power/reset/Makefile linux/drivers/power/reset/Makefile +--- linux.orig/drivers/power/reset/Makefile 2023-09-12 12:02:58.741642619 +0000 ++++ linux/drivers/power/reset/Makefile 2023-09-12 12:03:27.490291628 +0000 +@@ -17,6 +17,7 @@ obj-$(CONFIG_POWER_RESET_MT6323) += mt63 + obj-$(CONFIG_POWER_RESET_OXNAS) += oxnas-restart.o + obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o + obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o ++obj-$(CONFIG_POWER_RESET_ODROID_GO_ULTRA_POWEROFF) += odroid-go-ultra-poweroff.o + obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o + obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o + obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o +diff -rupN linux.orig/drivers/power/reset/odroid-go-ultra-poweroff.c linux/drivers/power/reset/odroid-go-ultra-poweroff.c +--- linux.orig/drivers/power/reset/odroid-go-ultra-poweroff.c 1970-01-01 00:00:00.000000000 +0000 ++++ linux/drivers/power/reset/odroid-go-ultra-poweroff.c 2023-09-12 12:03:27.490291628 +0000 +@@ -0,0 +1,177 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (c) 2023 Neil Armstrong ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * The Odroid Go Ultra has 2 PMICs: ++ * - RK818 (manages the battery and USB-C power supply) ++ * - RK817 ++ * Both PMICs feeds power to the S922X SoC, so they must be powered-off in sequence. ++ * Vendor does power-off the RK817 first, then the RK818 so here we follow this sequence. ++ */ ++ ++struct odroid_go_ultra_poweroff_data { ++ struct device *dev; ++ struct device *rk817; ++ struct device *rk818; ++}; ++ ++static int odroid_go_ultra_poweroff_prepare(struct sys_off_data *data) ++{ ++ struct odroid_go_ultra_poweroff_data *poweroff_data = data->cb_data; ++ struct regmap *rk817, *rk818; ++ int ret; ++ ++ /* RK817 Regmap */ ++ rk817 = dev_get_regmap(poweroff_data->rk817, NULL); ++ if (!rk817) { ++ dev_err(poweroff_data->dev, "failed to get rk817 regmap\n"); ++ return notifier_from_errno(-EINVAL); ++ } ++ ++ /* RK818 Regmap */ ++ rk818 = dev_get_regmap(poweroff_data->rk818, NULL); ++ if (!rk818) { ++ dev_err(poweroff_data->dev, "failed to get rk818 regmap\n"); ++ return notifier_from_errno(-EINVAL); ++ } ++ ++ dev_info(poweroff_data->dev, "Setting PMICs for power off"); ++ ++ /* RK817 */ ++ ret = regmap_update_bits(rk817, RK817_SYS_CFG(3), DEV_OFF, DEV_OFF); ++ if (ret) { ++ dev_err(poweroff_data->dev, "failed to poweroff rk817\n"); ++ return notifier_from_errno(ret); ++ } ++ ++ /* RK818 */ ++ ret = regmap_update_bits(rk818, RK818_DEVCTRL_REG, DEV_OFF, DEV_OFF); ++ if (ret) { ++ dev_err(poweroff_data->dev, "failed to poweroff rk818\n"); ++ return notifier_from_errno(ret); ++ } ++ ++ return NOTIFY_OK; ++} ++ ++static void odroid_go_ultra_poweroff_put_pmic_device(void *data) ++{ ++ struct device *dev = data; ++ ++ put_device(dev); ++} ++ ++static int odroid_go_ultra_poweroff_get_pmic_device(struct device *dev, const char *compatible, ++ struct device **pmic) ++{ ++ struct device_node *pmic_node; ++ struct i2c_client *pmic_client; ++ ++ pmic_node = of_find_compatible_node(NULL, NULL, compatible); ++ if (!pmic_node) ++ return -ENODEV; ++ ++ pmic_client = of_find_i2c_device_by_node(pmic_node); ++ of_node_put(pmic_node); ++ if (!pmic_client) ++ return -EPROBE_DEFER; ++ ++ *pmic = &pmic_client->dev; ++ ++ return devm_add_action_or_reset(dev, odroid_go_ultra_poweroff_put_pmic_device, *pmic); ++} ++ ++static int odroid_go_ultra_poweroff_probe(struct platform_device *pdev) ++{ ++ struct odroid_go_ultra_poweroff_data *poweroff_data; ++ int ret; ++ ++ poweroff_data = devm_kzalloc(&pdev->dev, sizeof(*poweroff_data), GFP_KERNEL); ++ if (!poweroff_data) ++ return -ENOMEM; ++ ++ dev_set_drvdata(&pdev->dev, poweroff_data); ++ ++ /* RK818 PMIC Device */ ++ ret = odroid_go_ultra_poweroff_get_pmic_device(&pdev->dev, "rockchip,rk818", ++ &poweroff_data->rk818); ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, "failed to get rk818 mfd data\n"); ++ ++ /* RK817 PMIC Device */ ++ ret = odroid_go_ultra_poweroff_get_pmic_device(&pdev->dev, "rockchip,rk817", ++ &poweroff_data->rk817); ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, "failed to get rk817 mfd data\n"); ++ ++ /* Register as SYS_OFF_MODE_POWER_OFF_PREPARE because regmap_update_bits may sleep */ ++ ret = devm_register_sys_off_handler(&pdev->dev, ++ SYS_OFF_MODE_POWER_OFF_PREPARE, ++ SYS_OFF_PRIO_DEFAULT, ++ odroid_go_ultra_poweroff_prepare, ++ poweroff_data); ++ if (ret) ++ return dev_err_probe(&pdev->dev, ret, "failed to register sys-off handler\n"); ++ ++ dev_info(&pdev->dev, "Registered Power-Off handler\n"); ++ ++ return 0; ++} ++static struct platform_device *pdev; ++ ++static struct platform_driver odroid_go_ultra_poweroff_driver = { ++ .driver = { ++ .name = "odroid-go-ultra-poweroff", ++ }, ++ .probe = odroid_go_ultra_poweroff_probe, ++}; ++ ++static int __init odroid_go_ultra_poweroff_init(void) ++{ ++ int ret; ++ ++ /* Only create when running on the Odroid Go Ultra device */ ++ if (!of_device_is_compatible(of_root, "hardkernel,odroid-go-ultra")) ++ return -ENODEV; ++ ++ ret = platform_driver_register(&odroid_go_ultra_poweroff_driver); ++ if (ret) ++ return ret; ++ ++ pdev = platform_device_register_resndata(NULL, "odroid-go-ultra-poweroff", -1, ++ NULL, 0, NULL, 0); ++ ++ if (IS_ERR(pdev)) { ++ platform_driver_unregister(&odroid_go_ultra_poweroff_driver); ++ return PTR_ERR(pdev); ++ } ++ ++ return 0; ++} ++ ++static void __exit odroid_go_ultra_poweroff_exit(void) ++{ ++ /* Only delete when running on the Odroid Go Ultra device */ ++ if (!of_device_is_compatible(of_root, "hardkernel,odroid-go-ultra")) ++ return; ++ ++ platform_device_unregister(pdev); ++ platform_driver_unregister(&odroid_go_ultra_poweroff_driver); ++} ++ ++module_init(odroid_go_ultra_poweroff_init); ++module_exit(odroid_go_ultra_poweroff_exit); ++ ++MODULE_AUTHOR("Neil Armstrong "); ++MODULE_DESCRIPTION("Odroid Go Ultra poweroff driver"); ++MODULE_LICENSE("GPL"); + diff --git a/projects/Amlogic/packages/linux/patches/S922X/004.03-polled-input-device-driver.patch b/projects/Amlogic/packages/linux/patches/S922X/004.03-polled-input-device-driver.patch new file mode 100644 index 000000000..c2377a6bc --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/004.03-polled-input-device-driver.patch @@ -0,0 +1,402 @@ +diff -rupN linux.orig/drivers/input/Kconfig linux/drivers/input/Kconfig +--- linux.orig/drivers/input/Kconfig 2023-09-12 12:02:58.173629790 +0000 ++++ linux/drivers/input/Kconfig 2023-09-12 12:03:27.490291628 +0000 +@@ -51,6 +51,19 @@ config INPUT_FF_MEMLESS + To compile this driver as a module, choose M here: the + module will be called ff-memless. + ++config INPUT_POLLDEV ++ tristate "Polled input device skeleton" ++ help ++ Say Y here if you are using a driver for an input ++ device that periodically polls hardware state. This ++ option is only useful for out-of-tree drivers since ++ in-tree drivers select it automatically. ++ ++ If unsure, say N. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called input-polldev. ++ + config INPUT_SPARSEKMAP + tristate "Sparse keymap support library" + help + +diff -rupN linux.orig/drivers/input/Makefile linux/drivers/input/Makefile +--- linux.orig/drivers/input/Makefile 2023-09-12 12:02:58.173629790 +0000 ++++ linux/drivers/input/Makefile 2023-09-12 12:03:27.490291628 +0000 +@@ -10,6 +10,7 @@ input-core-y := input.o input-compat.o i + input-core-y += touchscreen.o + + obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o ++obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o + obj-$(CONFIG_INPUT_SPARSEKMAP) += sparse-keymap.o + obj-$(CONFIG_INPUT_MATRIXKMAP) += matrix-keymap.o + obj-$(CONFIG_INPUT_VIVALDIFMAP) += vivaldi-fmap.o +diff -rupN linux.orig/drivers/input/input-polldev.c linux/drivers/input/input-polldev.c +--- linux.orig/drivers/input/input-polldev.c 1970-01-01 00:00:00.000000000 +0000 ++++ linux/drivers/input/input-polldev.c 2023-09-12 12:03:27.490291628 +0000 +@@ -0,0 +1,362 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Generic implementation of a polled input device ++ ++ * Copyright (c) 2007 Dmitry Torokhov ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Dmitry Torokhov "); ++MODULE_DESCRIPTION("Generic implementation of a polled input device"); ++MODULE_LICENSE("GPL v2"); ++ ++static void input_polldev_queue_work(struct input_polled_dev *dev) ++{ ++ unsigned long delay; ++ ++ delay = msecs_to_jiffies(dev->poll_interval); ++ if (delay >= HZ) ++ delay = round_jiffies_relative(delay); ++ ++ queue_delayed_work(system_freezable_wq, &dev->work, delay); ++} ++ ++static void input_polled_device_work(struct work_struct *work) ++{ ++ struct input_polled_dev *dev = ++ container_of(work, struct input_polled_dev, work.work); ++ ++ dev->poll(dev); ++ input_polldev_queue_work(dev); ++} ++ ++static int input_open_polled_device(struct input_dev *input) ++{ ++ struct input_polled_dev *dev = input_get_drvdata(input); ++ ++ if (dev->open) ++ dev->open(dev); ++ ++ /* Only start polling if polling is enabled */ ++ if (dev->poll_interval > 0) { ++ dev->poll(dev); ++ input_polldev_queue_work(dev); ++ } ++ ++ return 0; ++} ++ ++static void input_close_polled_device(struct input_dev *input) ++{ ++ struct input_polled_dev *dev = input_get_drvdata(input); ++ ++ cancel_delayed_work_sync(&dev->work); ++ ++ if (dev->close) ++ dev->close(dev); ++} ++ ++/* SYSFS interface */ ++ ++static ssize_t input_polldev_get_poll(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct input_polled_dev *polldev = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%d\n", polldev->poll_interval); ++} ++ ++static ssize_t input_polldev_set_poll(struct device *dev, ++ struct device_attribute *attr, const char *buf, ++ size_t count) ++{ ++ struct input_polled_dev *polldev = dev_get_drvdata(dev); ++ struct input_dev *input = polldev->input; ++ unsigned int interval; ++ int err; ++ ++ err = kstrtouint(buf, 0, &interval); ++ if (err) ++ return err; ++ ++ if (interval < polldev->poll_interval_min) ++ return -EINVAL; ++ ++ if (interval > polldev->poll_interval_max) ++ return -EINVAL; ++ ++ mutex_lock(&input->mutex); ++ ++ polldev->poll_interval = interval; ++ ++ if (input->users) { ++ cancel_delayed_work_sync(&polldev->work); ++ if (polldev->poll_interval > 0) ++ input_polldev_queue_work(polldev); ++ } ++ ++ mutex_unlock(&input->mutex); ++ ++ return count; ++} ++ ++static DEVICE_ATTR(poll, S_IRUGO | S_IWUSR, input_polldev_get_poll, ++ input_polldev_set_poll); ++ ++ ++static ssize_t input_polldev_get_max(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct input_polled_dev *polldev = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%d\n", polldev->poll_interval_max); ++} ++ ++static DEVICE_ATTR(max, S_IRUGO, input_polldev_get_max, NULL); ++ ++static ssize_t input_polldev_get_min(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct input_polled_dev *polldev = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%d\n", polldev->poll_interval_min); ++} ++ ++static DEVICE_ATTR(min, S_IRUGO, input_polldev_get_min, NULL); ++ ++static struct attribute *sysfs_attrs[] = { ++ &dev_attr_poll.attr, ++ &dev_attr_max.attr, ++ &dev_attr_min.attr, ++ NULL ++}; ++ ++static struct attribute_group input_polldev_attribute_group = { ++ .attrs = sysfs_attrs ++}; ++ ++static const struct attribute_group *input_polldev_attribute_groups[] = { ++ &input_polldev_attribute_group, ++ NULL ++}; ++ ++/** ++ * input_allocate_polled_device - allocate memory for polled device ++ * ++ * The function allocates memory for a polled device and also ++ * for an input device associated with this polled device. ++ */ ++struct input_polled_dev *input_allocate_polled_device(void) ++{ ++ struct input_polled_dev *dev; ++ ++ dev = kzalloc(sizeof(struct input_polled_dev), GFP_KERNEL); ++ if (!dev) ++ return NULL; ++ ++ dev->input = input_allocate_device(); ++ if (!dev->input) { ++ kfree(dev); ++ return NULL; ++ } ++ ++ return dev; ++} ++EXPORT_SYMBOL(input_allocate_polled_device); ++ ++struct input_polled_devres { ++ struct input_polled_dev *polldev; ++}; ++ ++static int devm_input_polldev_match(struct device *dev, void *res, void *data) ++{ ++ struct input_polled_devres *devres = res; ++ ++ return devres->polldev == data; ++} ++ ++static void devm_input_polldev_release(struct device *dev, void *res) ++{ ++ struct input_polled_devres *devres = res; ++ struct input_polled_dev *polldev = devres->polldev; ++ ++ dev_dbg(dev, "%s: dropping reference/freeing %s\n", ++ __func__, dev_name(&polldev->input->dev)); ++ ++ input_put_device(polldev->input); ++ kfree(polldev); ++} ++ ++static void devm_input_polldev_unregister(struct device *dev, void *res) ++{ ++ struct input_polled_devres *devres = res; ++ struct input_polled_dev *polldev = devres->polldev; ++ ++ dev_dbg(dev, "%s: unregistering device %s\n", ++ __func__, dev_name(&polldev->input->dev)); ++ input_unregister_device(polldev->input); ++ ++ /* ++ * Note that we are still holding extra reference to the input ++ * device so it will stick around until devm_input_polldev_release() ++ * is called. ++ */ ++} ++ ++/** ++ * devm_input_allocate_polled_device - allocate managed polled device ++ * @dev: device owning the polled device being created ++ * ++ * Returns prepared &struct input_polled_dev or %NULL. ++ * ++ * Managed polled input devices do not need to be explicitly unregistered ++ * or freed as it will be done automatically when owner device unbinds ++ * from * its driver (or binding fails). Once such managed polled device ++ * is allocated, it is ready to be set up and registered in the same ++ * fashion as regular polled input devices (using ++ * input_register_polled_device() function). ++ * ++ * If you want to manually unregister and free such managed polled devices, ++ * it can be still done by calling input_unregister_polled_device() and ++ * input_free_polled_device(), although it is rarely needed. ++ * ++ * NOTE: the owner device is set up as parent of input device and users ++ * should not override it. ++ */ ++struct input_polled_dev *devm_input_allocate_polled_device(struct device *dev) ++{ ++ struct input_polled_dev *polldev; ++ struct input_polled_devres *devres; ++ ++ devres = devres_alloc(devm_input_polldev_release, sizeof(*devres), ++ GFP_KERNEL); ++ if (!devres) ++ return NULL; ++ ++ polldev = input_allocate_polled_device(); ++ if (!polldev) { ++ devres_free(devres); ++ return NULL; ++ } ++ ++ polldev->input->dev.parent = dev; ++ polldev->devres_managed = true; ++ ++ devres->polldev = polldev; ++ devres_add(dev, devres); ++ ++ return polldev; ++} ++EXPORT_SYMBOL(devm_input_allocate_polled_device); ++ ++/** ++ * input_free_polled_device - free memory allocated for polled device ++ * @dev: device to free ++ * ++ * The function frees memory allocated for polling device and drops ++ * reference to the associated input device. ++ */ ++void input_free_polled_device(struct input_polled_dev *dev) ++{ ++ if (dev) { ++ if (dev->devres_managed) ++ WARN_ON(devres_destroy(dev->input->dev.parent, ++ devm_input_polldev_release, ++ devm_input_polldev_match, ++ dev)); ++ input_put_device(dev->input); ++ kfree(dev); ++ } ++} ++EXPORT_SYMBOL(input_free_polled_device); ++ ++/** ++ * input_register_polled_device - register polled device ++ * @dev: device to register ++ * ++ * The function registers previously initialized polled input device ++ * with input layer. The device should be allocated with call to ++ * input_allocate_polled_device(). Callers should also set up poll() ++ * method and set up capabilities (id, name, phys, bits) of the ++ * corresponding input_dev structure. ++ */ ++int input_register_polled_device(struct input_polled_dev *dev) ++{ ++ struct input_polled_devres *devres = NULL; ++ struct input_dev *input = dev->input; ++ int error; ++ ++ if (dev->devres_managed) { ++ devres = devres_alloc(devm_input_polldev_unregister, ++ sizeof(*devres), GFP_KERNEL); ++ if (!devres) ++ return -ENOMEM; ++ ++ devres->polldev = dev; ++ } ++ ++ input_set_drvdata(input, dev); ++ INIT_DELAYED_WORK(&dev->work, input_polled_device_work); ++ ++ if (!dev->poll_interval) ++ dev->poll_interval = 500; ++ if (!dev->poll_interval_max) ++ dev->poll_interval_max = dev->poll_interval; ++ ++ input->open = input_open_polled_device; ++ input->close = input_close_polled_device; ++ ++ input->dev.groups = input_polldev_attribute_groups; ++ ++ error = input_register_device(input); ++ if (error) { ++ devres_free(devres); ++ return error; ++ } ++ ++ /* ++ * Take extra reference to the underlying input device so ++ * that it survives call to input_unregister_polled_device() ++ * and is deleted only after input_free_polled_device() ++ * has been invoked. This is needed to ease task of freeing ++ * sparse keymaps. ++ */ ++ input_get_device(input); ++ ++ if (dev->devres_managed) { ++ dev_dbg(input->dev.parent, "%s: registering %s with devres.\n", ++ __func__, dev_name(&input->dev)); ++ devres_add(input->dev.parent, devres); ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(input_register_polled_device); ++ ++/** ++ * input_unregister_polled_device - unregister polled device ++ * @dev: device to unregister ++ * ++ * The function unregisters previously registered polled input ++ * device from input layer. Polling is stopped and device is ++ * ready to be freed with call to input_free_polled_device(). ++ */ ++void input_unregister_polled_device(struct input_polled_dev *dev) ++{ ++ if (dev->devres_managed) ++ WARN_ON(devres_destroy(dev->input->dev.parent, ++ devm_input_polldev_unregister, ++ devm_input_polldev_match, ++ dev)); ++ ++ input_unregister_device(dev->input); ++} ++EXPORT_SYMBOL(input_unregister_polled_device); + diff --git a/projects/Amlogic/packages/linux/patches/S922X/000-s922x-devices.patch b/projects/Amlogic/packages/linux/patches/S922X/004.04-rk818-charger-driver.patch similarity index 56% rename from projects/Amlogic/packages/linux/patches/S922X/000-s922x-devices.patch rename to projects/Amlogic/packages/linux/patches/S922X/004.04-rk818-charger-driver.patch index 0b0079d91..807c7e379 100644 --- a/projects/Amlogic/packages/linux/patches/S922X/000-s922x-devices.patch +++ b/projects/Amlogic/packages/linux/patches/S922X/004.04-rk818-charger-driver.patch @@ -1,3966 +1,3 @@ -diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/Makefile linux/arch/arm64/boot/dts/amlogic/Makefile ---- linux.orig/arch/arm64/boot/dts/amlogic/Makefile 2023-09-12 12:02:56.937601871 +0000 -+++ linux/arch/arm64/boot/dts/amlogic/Makefile 2023-09-12 12:03:27.490291628 +0000 -@@ -12,8 +12,10 @@ dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gsking-x.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking-pro.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-gtking.dtb -+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-go-ultra.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2-plus.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb -+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-powkiddy-rgb10-max-3.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-g12b-ugoos-am6.dtb - dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-kii-pro.dtb -diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi ---- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi 2023-09-12 12:02:56.937601871 +0000 -+++ linux/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi 2023-09-12 12:03:27.490291628 +0000 -@@ -61,18 +61,6 @@ - gpu_opp_table: opp-table-gpu { - compatible = "operating-points-v2"; - -- opp-124999998 { -- opp-hz = /bits/ 64 <124999998>; -- opp-microvolt = <800000>; -- }; -- opp-249999996 { -- opp-hz = /bits/ 64 <249999996>; -- opp-microvolt = <800000>; -- }; -- opp-285714281 { -- opp-hz = /bits/ 64 <285714281>; -- opp-microvolt = <800000>; -- }; - opp-399999994 { - opp-hz = /bits/ 64 <399999994>; - opp-microvolt = <800000>; -@@ -1884,6 +1872,15 @@ - }; - }; - -+ uart_ao_b_pins: uart-b-ao { -+ mux { -+ groups = "uart_ao_b_tx_8", -+ "uart_ao_b_rx_9"; -+ function = "uart_ao_b"; -+ bias-disable; -+ }; -+ }; -+ - uart_ao_a_pins: uart-a-ao { - mux { - groups = "uart_ao_a_tx", -@@ -2394,14 +2391,20 @@ - }; - - mali: gpu@ffe40000 { -- compatible = "amlogic,meson-g12a-mali", "arm,mali-bifrost"; -- reg = <0x0 0xffe40000 0x0 0x40000>; -+ compatible = "arm,mali-midgard"; -+ reg = <0x0 0xffe40000 0x0 0x40000>, -+ <0 0xFFD01000 0 0x01000>, -+ <0 0xFF800000 0 0x01000>, -+ <0 0xFF63c000 0 0x01000>, -+ <0 0xFFD01000 0 0x01000>; -+ - interrupt-parent = <&gic>; -- interrupts = , -+ interrupts = , - , -- ; -- interrupt-names = "job", "mmu", "gpu"; -+ ; -+ interrupt-names = "GPU", "MMU", "JOB"; - clocks = <&clkc CLKID_MALI>; -+ clock-names = "clk_mali"; - resets = <&reset RESET_DVALIN_CAPB3>, <&reset RESET_DVALIN>; - operating-points-v2 = <&gpu_opp_table>; - #cooling-cells = <2>; -diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi ---- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi 2023-09-12 12:02:56.937601871 +0000 -+++ linux/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi 2023-09-12 12:03:27.490291628 +0000 -@@ -11,6 +11,11 @@ - compatible = "operating-points-v2"; - opp-shared; - -+ opp-667000000 { -+ opp-hz = /bits/ 64 <667000000>; -+ opp-microvolt = <731000>; -+ }; -+ - opp-1000000000 { - opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <761000>; -@@ -51,6 +56,11 @@ - compatible = "operating-points-v2"; - opp-shared; - -+ opp-667000000 { -+ opp-hz = /bits/ 64 <667000000>; -+ opp-microvolt = <731000>; -+ }; -+ - opp-1000000000 { - opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <731000>; -diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts linux/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts ---- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts 1970-01-01 00:00:00.000000000 +0000 -+++ linux/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts 2023-09-12 13:20:28.956694441 +0000 -@@ -0,0 +1,1021 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2022 Neil Armstrong -+ */ -+ -+/dts-v1/; -+ -+#include "meson-g12b-s922x.dtsi" -+#include -+#include -+#include -+#include -+#include -+ -+/ { -+ compatible = "hardkernel,odroid-go-ultra", "amlogic,s922x", "amlogic,g12b"; -+ model = "Hardkernel ODROID-GO-Ultra"; -+ -+ aliases { -+ serial0 = &uart_AO; -+ rtc0 = &vrtc; -+ mmc0 = &sd_emmc_c; -+ mmc1 = &sd_emmc_b; -+ }; -+ -+ panel_backlight: backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&pwm_ef 1 40000 0>; -+ brightness-levels = <0 255>; -+ num-interpolated-steps = <255>; -+ default-brightness-level = <255>; -+ }; -+ -+ bat: battery { -+ compatible = "simple-battery"; -+ voltage-max-design-microvolt = <4200000>; -+ voltage-min-design-microvolt = <3500000>; -+ charge-full-design-microamp-hours = <4000000>; -+ charge-term-current-microamp = <200000>; -+ constant-charge-current-max-microamp = <1500000>; -+ constant-charge-voltage-max-microvolt = <4200000>; -+ factory-internal-resistance-micro-ohms = <180000>; -+ -+ -+ ocv-capacity-celsius = <20>; -+ ocv-capacity-table-0 = <4146950 100>, <4001920 95>, <3967900 90>, <3919950 85>, -+ <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, -+ <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, -+ <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, -+ <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, -+ <3574170 0>; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ codec_clk: codec-clk { -+ compatible = "fixed-clock"; -+ clock-frequency = <12288000>; -+ clock-output-names = "codec_clk"; -+ #clock-cells = <0>; -+ }; -+ -+ gpio_keys: volume-keys { -+ compatible = "gpio-keys-polled"; -+ poll-interval = <5>; -+ autorepeat; -+ -+ volume-up-button { -+ label = "VOLUME-UP"; -+ linux,code = ; -+ gpios = <&gpio GPIOX_8 GPIO_ACTIVE_LOW>; -+ }; -+ volume-down-button { -+ label = "VOLUME-DOWN"; -+ linux,code = ; -+ gpios = <&gpio GPIOX_9 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ hp_detect_switch: hp-detect-switch { -+ compatible = "gpio-keys-polled"; -+ poll-interval = <5>; -+ autorepeat; -+ -+ hp-detect-pin { -+ label = "HEADPHONE"; -+ linux,input-type = ; -+ linux,code = ; -+ gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ joypad: gou_joypad { -+ compatible = "odroidgou-joypad"; -+ poll-interval = <10>; -+ pinctrl-0 = <&keypad_gpio_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ -+ joypad-name = "GO-Ultra Gamepad"; -+ //joypad-vendor = <0x045e>; -+ joypad-product = <0x1000>; -+ joypad-revision = <0x0100>; -+ -+ /* Analog sticks */ -+ io-channels = <&saradc 0>, <&saradc 1>, <&saradc 2>, <&saradc 3>; -+ io-channel-names = "key-RY", "key-RX", "key-LY", "key-LX"; -+ button-adc-scale = <4>; -+ button-adc-deadzone = <64>; -+ button-adc-fuzz = <32>; -+ button-adc-flat = <32>; -+ abs_x-p-tuning = <350>; -+ abs_x-n-tuning = <350>; -+ abs_y-p-tuning = <350>; -+ abs_y-n-tuning = <350>; -+ abs_rx-p-tuning = <350>; -+ abs_rx-n-tuning = <350>; -+ abs_ry-p-tuning = <350>; -+ abs_ry-n-tuning = <350>; -+ -+ /* Buttons */ -+ sw1 { -+ gpios = <&gpio GPIOX_0 GPIO_ACTIVE_LOW>; -+ label = "GPIO DPAD-UP"; -+ linux,code = ; // 0x220 -+ }; -+ sw2 { -+ gpios = <&gpio GPIOX_1 GPIO_ACTIVE_LOW>; -+ label = "GPIO DPAD-DOWN"; -+ linux,code = ; // 0x221 -+ }; -+ sw3 { -+ gpios = <&gpio GPIOX_2 GPIO_ACTIVE_LOW>; -+ label = "GPIO DPAD-LEFT"; -+ linux,code = ; // 0x222 -+ }; -+ sw4 { -+ gpios = <&gpio GPIOX_3 GPIO_ACTIVE_LOW>; -+ label = "GPIO DPAD-RIGHT"; -+ linux,code = ; // 0x223 -+ }; -+ sw5 { -+ gpios = <&gpio GPIOX_4 GPIO_ACTIVE_LOW>; -+ label = "GPIO BTN-A"; -+ linux,code = ; // 0x131 -+ }; -+ sw6 { -+ gpios = <&gpio GPIOX_5 GPIO_ACTIVE_LOW>; -+ label = "GPIO BTN-B"; -+ linux,code = ; // 0x130 -+ }; -+ sw7 { -+ gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; -+ label = "GPIO BTN-Y"; -+ linux,code = ; // 0x134 -+ }; -+ sw8 { -+ gpios = <&gpio GPIOX_7 GPIO_ACTIVE_LOW>; -+ label = "GPIO BTN-X"; -+ linux,code = ; // 0x133 -+ }; -+ sw11 { -+ gpios = <&gpio GPIOX_10 GPIO_ACTIVE_LOW>; -+ label = "GPIO F2"; -+ linux,code = ; // 0x2c2 -+ }; -+ sw12 { -+ gpios = <&gpio GPIOX_11 GPIO_ACTIVE_LOW>; -+ label = "GPIO F3"; -+ linux,code = ; // 0x2c3 -+ }; -+ sw13 { -+ gpios = <&gpio GPIOX_12 GPIO_ACTIVE_LOW>; -+ label = "GPIO F4"; -+ linux,code = ; // 0x2c4 -+ }; -+ sw14 { -+ gpios = <&gpio GPIOX_13 GPIO_ACTIVE_LOW>; -+ label = "GPIO F5"; -+ linux,code = ; // 0x13c -+ }; -+ sw15 { -+ gpios = <&gpio GPIOX_14 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-LEFT"; -+ linux,code = ; // 0x02 -+ }; -+ sw16 { -+ gpios = <&gpio GPIOX_15 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-RIGHT"; -+ linux,code = ; // 0x05 -+ }; -+ sw17 { -+ gpios = <&gpio GPIOX_16 GPIO_ACTIVE_LOW>; -+ label = "GPIO F6"; -+ linux,code = ; -+ }; -+ sw18 { -+ gpios = <&gpio GPIOX_17 GPIO_ACTIVE_LOW>; -+ label = "GPIO F1"; -+ linux,code = ; -+ }; -+ sw19 { -+ gpios = <&gpio GPIOX_18 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-RIGHT2"; -+ linux,code = ; -+ }; -+ sw20 { -+ gpios = <&gpio GPIOX_19 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-LEFT2"; -+ linux,code = ; -+ }; -+ }; -+ -+ memory@0 { -+ device_type = "memory"; -+ reg = <0x0 0x0 0x0 0x40000000>; -+ }; -+ -+ emmc_pwrseq: emmc-pwrseq { -+ compatible = "mmc-pwrseq-emmc"; -+ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ led-blue { -+ color = ; -+ function = LED_FUNCTION_STATUS; -+ gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "none"; -+ }; -+ -+ led-red { -+ color = ; -+ function = LED_FUNCTION_STATUS; -+ gpios = <&gpio_ao GPIOAO_6 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ poweroff { -+ compatible = "hardkernel,odroid-go-ultra-poweroff"; -+ hardkernel,rk817-pmic = <&rk817>; -+ hardkernel,rk818-pmic = <&rk818>; -+ }; -+ -+ vdd_sys: regulator-vdd_sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "VDD_SYS"; -+ regulator-min-microvolt = <3800000>; -+ regulator-max-microvolt = <3800000>; -+ regulator-always-on; -+ }; -+ -+ sound { -+ compatible = "amlogic,axg-sound-card"; -+ model = "ODROID-GO-ULTRA"; -+ audio-aux-devs = <&tdmout_b>; -+ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", -+ "TDM_B Playback", "TDMOUT_B OUT"; -+ -+ assigned-clocks = <&clkc CLKID_MPLL2>, -+ <&clkc CLKID_MPLL0>, -+ <&clkc CLKID_MPLL1>; -+ assigned-clock-parents = <0>, <0>, <0>; -+ assigned-clock-rates = <294912000>, -+ <270950400>, -+ <393216000>; -+ status = "okay"; -+ -+ dai-link-0 { -+ sound-dai = <&frddr_a>; -+ }; -+ -+ dai-link-1 { -+ sound-dai = <&frddr_b>; -+ }; -+ -+ dai-link-2 { -+ sound-dai = <&frddr_c>; -+ }; -+ -+ dai-link-3 { -+ sound-dai = <&toddr_a>; -+ }; -+ -+ dai-link-4 { -+ sound-dai = <&toddr_b>; -+ }; -+ -+ dai-link-5 { -+ sound-dai = <&toddr_c>; -+ }; -+ -+ /* 8ch hdmi interface */ -+ dai-link-6 { -+ sound-dai = <&tdmif_b>; -+ dai-format = "i2s"; -+ dai-tdm-slot-tx-mask-0 = <1 1>; -+ dai-tdm-slot-tx-mask-1 = <1 1>; -+ mclk-fs = <256>; -+ -+ codec-0 { -+ sound-dai = <&rk817>; -+ }; -+ }; -+ }; -+}; -+ -+&arb { -+ status = "okay"; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vddcpu_b>; -+ operating-points-v2 = <&cpu_opp_table_0>; -+ clocks = <&clkc CLKID_CPU_CLK>; -+ clock-latency = <50000>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vddcpu_b>; -+ operating-points-v2 = <&cpu_opp_table_0>; -+ clocks = <&clkc CLKID_CPU_CLK>; -+ clock-latency = <50000>; -+}; -+ -+&cpu100 { -+ cpu-supply = <&vddcpu_a>; -+ operating-points-v2 = <&cpub_opp_table_1>; -+ clocks = <&clkc CLKID_CPUB_CLK>; -+ clock-latency = <50000>; -+}; -+ -+&cpu101 { -+ cpu-supply = <&vddcpu_a>; -+ operating-points-v2 = <&cpub_opp_table_1>; -+ clocks = <&clkc CLKID_CPUB_CLK>; -+ clock-latency = <50000>; -+}; -+ -+&cpu102 { -+ cpu-supply = <&vddcpu_a>; -+ operating-points-v2 = <&cpub_opp_table_1>; -+ clocks = <&clkc CLKID_CPUB_CLK>; -+ clock-latency = <50000>; -+}; -+ -+&cpu103 { -+ cpu-supply = <&vddcpu_a>; -+ operating-points-v2 = <&cpub_opp_table_1>; -+ clocks = <&clkc CLKID_CPUB_CLK>; -+ clock-latency = <50000>; -+}; -+ -+/* RK817 only supports 12.5mV steps, round up the values */ -+&cpu_opp_table_0 { -+ opp-667000000 { -+ opp-microvolt = <725000>; -+ }; -+ opp-1000000000 { -+ opp-microvolt = <737500>; -+ }; -+ opp-1200000000 { -+ opp-microvolt = <737500>; -+ }; -+ opp-1398000000 { -+ opp-microvolt = <762500>; -+ }; -+ opp-1512000000 { -+ opp-microvolt = <800000>; -+ }; -+ opp-1608000000 { -+ opp-microvolt = <837500>; -+ }; -+ opp-1704000000 { -+ opp-microvolt = <862500>; -+ }; -+ opp-1896000000 { -+ opp-microvolt = <987500>; -+ }; -+ opp-1992000000 { -+ opp-microvolt = <1050000>; -+ }; -+ opp-2016000000 { -+ opp-hz = /bits/ 64 <2016000000>; -+ opp-microvolt = <1050000>; -+ }; -+}; -+ -+/* RK818 only supports 12.5mV steps, round up the values */ -+&cpub_opp_table_1 { -+ opp-667000000 { -+ opp-microvolt = <750000>; -+ }; -+ opp-1000000000 { -+ opp-microvolt = <775000>; -+ }; -+ opp-1200000000 { -+ opp-microvolt = <775000>; -+ }; -+ opp-1398000000 { -+ opp-microvolt = <800000>; -+ }; -+ opp-1512000000 { -+ opp-microvolt = <825000>; -+ }; -+ opp-1608000000 { -+ opp-microvolt = <862500>; -+ }; -+ opp-1704000000 { -+ opp-microvolt = <900000>; -+ }; -+ opp-1800000000 { -+ opp-microvolt = <987500>; -+ }; -+ opp-1908000000 { -+ opp-microvolt = <1025000>; -+ }; -+ opp-2016000000 { -+ opp-hz = /bits/ 64 <2016000000>; -+ opp-microvolt = <1025000>; -+ }; -+ opp-2100000000 { -+ opp-hz = /bits/ 64 <2100000000>; -+ opp-microvolt = <1025000>; -+ }; -+ opp-2208000000 { -+ opp-hz = /bits/ 64 <2208000000>; -+ opp-microvolt = <1050000>; -+ }; -+ opp-2304000000 { -+ opp-hz = /bits/ 64 <2304000000>; -+ opp-microvolt = <1050000>; -+ }; -+ opp-2400000000 { -+ opp-hz = /bits/ 64 <2400000000>; -+ opp-microvolt = <1050000>; -+ }; -+}; -+ -+&i2c_AO { -+ status = "okay"; -+ pinctrl-0 = <&i2c_ao_sck_pins>, <&i2c_ao_sda_pins>; -+ pinctrl-names = "default"; -+ -+ rk818: pmic@1c { -+ compatible = "rockchip,rk818"; -+ reg = <0x1c>; -+ interrupt-parent = <&gpio_intc>; -+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; /* GPIOAO_7 */ -+ rockchip,system-power-controller; -+ clock-output-names = "rk808-clkout1", "rk808-clkout2"; -+ -+ vcc1-supply = <&vdd_sys>; -+ vcc2-supply = <&vdd_sys>; -+ vcc3-supply = <&vdd_sys>; -+ vcc4-supply = <&vdd_sys>; -+ vcc6-supply = <&vdd_sys>; -+ vcc7-supply = <&vcc_2v3>; -+ vcc8-supply = <&vcc_2v3>; -+ vcc9-supply = <&vddao_3v3>; -+ boost-supply = <&vdd_sys>; -+ switch-supply = <&vdd_sys>; -+ -+ regulators { -+ vddcpu_a: DCDC_REG1 { -+ regulator-name = "vddcpu_a"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1050000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <750000>; -+ }; -+ }; -+ -+ vdd_ee: DCDC_REG2 { -+ regulator-name = "vdd_ee"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <875000>; -+ regulator-max-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <875000>; -+ }; -+ }; -+ -+ vddq_1v1: DCDC_REG3 { -+ regulator-name = "vddq_1v1"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vddao_3v3: DCDC_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-name = "vddao_3v3"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ hp_5v: DCDC_BOOST { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-name = "hp_5v"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG1 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO1"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG2 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO2"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG3 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO3"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG4 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO4"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vddio_ao1v8: LDO_REG5 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vddio_ao1v8"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ LDO_REG6 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO6"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vddq_1v8: LDO_REG7 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vddq_1v8"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ LDO_REG8 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO8"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vddio_c: LDO_REG9 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vddio_c"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcc_sd: SWITCH_REG { -+ regulator-name = "vcc_sd"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ rk818_otg_switch: OTG_SWITCH { -+ regulator-name = "otg_switch"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ -+ battery { -+ compatible = "rockchip,rk818-battery"; -+ -+ ocv_table = < -+ 3470 3599 3671 3701 3728 3746 3762 -+ 3772 3781 3792 3816 3836 3866 3910 -+ 3942 3971 4002 4050 4088 4132 4200>; -+ design_capacity = <4000>; -+ design_qmax = <4100>; -+ bat_res = <180>; -+ max_input_current = <2000>; -+ max_chrg_current = <1500>; -+ max_chrg_voltage = <4250>; -+ sleep_enter_current = <300>; -+ sleep_exit_current = <300>; -+ power_off_thresd = <3450>; -+ zero_algorithm_vol = <3700>; -+ fb_temperature = <105>; -+ sample_res = <10>; -+ max_soc_offset = <60>; -+ energy_mode = <0>; -+ monitor_sec = <5>; -+ virtual_power = <0>; -+ power_dc2otg = <0>; -+ otg5v_suspend_enable = <0>; -+ }; -+ -+ charger { -+ compatible = "rockchip,rk818-charger"; -+ monitored-battery = <&bat>; -+ }; -+ -+ }; -+}; -+ -+&i2c3 { -+ status = "okay"; -+ pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>; -+ pinctrl-names = "default"; -+ -+ rk817: pmic@20 { -+ compatible = "rockchip,rk817"; -+ reg = <0x20>; -+ status = "okay"; -+ interrupt-parent = <&gpio_intc>; -+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>; /* GPIOAO_5 */ -+ wakeup-source; -+ -+ vcc1-supply = <&vdd_sys>; -+ vcc2-supply = <&vdd_sys>; -+ vcc3-supply = <&vdd_sys>; -+ vcc4-supply = <&vdd_sys>; -+ vcc5-supply = <&vdd_sys>; -+ vcc6-supply = <&vdd_sys>; -+ vcc7-supply = <&vdd_sys>; -+ vcc8-supply = <&vdd_sys>; -+ vcc9-supply = <&rk817_boost>; -+ -+ #sound-dai-cells = <0>; -+ clocks = <&codec_clk>; -+ clock-names = "mclk"; -+ -+ regulators { -+ DCDC_REG1 { -+ regulator-boot-off; -+ regulator-name = "rk817_BUCK1"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vddcpu_b: DCDC_REG2 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <725000>; -+ regulator-max-microvolt = <1050000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vddcpu_b"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1000000>; -+ }; -+ }; -+ -+ vcc_2v3: DCDC_REG3 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <2300000>; -+ regulator-max-microvolt = <2400000>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vcc_2v3"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ DCDC_REG4 { -+ regulator-boot-off; -+ regulator-name = "rk817_BUCK4"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG1 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO1"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG2 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO2"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG3 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO3"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vdd_codec"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG5 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO5"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG6 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO6"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG7 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO7"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_lcd: LDO_REG8 { -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-name = "vcc_lcd"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG9 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO9"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ rk817_boost: BOOST { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5400000>; -+ regulator-name = "rk817_boost"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ usb_host: OTG_SWITCH { -+ regulator-name = "usb_host"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ -+ rk817_codec: codec { -+ rockchip,mic-in-differential; -+ }; -+ }; -+}; -+ -+&clkc_audio { -+ status = "okay"; -+}; -+ -+ð_phy { -+ status = "disabled"; -+}; -+ -+&frddr_a { -+ status = "okay"; -+}; -+ -+&frddr_b { -+ status = "okay"; -+}; -+ -+&frddr_c { -+ status = "okay"; -+}; -+ -+&toddr_a { -+ status = "okay"; -+}; -+ -+&toddr_b { -+ status = "okay"; -+}; -+ -+&toddr_c { -+ status = "okay"; -+}; -+ -+&mipi_dsi { -+ status = "okay"; -+ -+ assigned-clocks = <&clkc CLKID_GP0_PLL>, -+ <&clkc CLKID_MIPI_DSI_PXCLK_SEL>, -+ <&clkc CLKID_MIPI_DSI_PXCLK>, -+ <&clkc CLKID_CTS_ENCL_SEL>, -+ <&clkc CLKID_VCLK2_SEL>; -+ assigned-clock-parents = <0>, -+ <&clkc CLKID_GP0_PLL>, -+ <0>, -+ <&clkc CLKID_VCLK2_DIV1>, -+ <&clkc CLKID_GP0_PLL>; -+ assigned-clock-rates = <344976000>, -+ <0>, -+ <344976000>, -+ <0>, -+ <0>; -+ -+ panel@0 { -+ compatible = "elida,kd50t048a", "sitronix,st7701"; -+ reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_HIGH>; -+ IOVCC-supply = <&vcc_lcd>; -+ VCC-supply = <&vcc_lcd>; -+ backlight = <&panel_backlight>; -+ rotation = <270>; -+ reg = <0>; -+ -+ port { -+ mipi_in_panel: endpoint { -+ remote-endpoint = <&mipi_out_panel>; -+ }; -+ }; -+ }; -+}; -+ -+&mipi_analog_dphy { -+ status = "okay"; -+}; -+ -+&mipi_dphy { -+ status = "okay"; -+}; -+ -+&mipi_dsi_panel_port { -+ mipi_out_panel: endpoint { -+ remote-endpoint = <&mipi_in_panel>; -+ }; -+}; -+ -+&periphs_pinctrl { -+ keypad_gpio_pins: keypad-gpio { -+ mux { -+ groups = "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", -+ "GPIOX_4", "GPIOX_5", "GPIOX_6", "GPIOX_7", -+ "GPIOX_8", "GPIOX_9", "GPIOX_10", "GPIOX_11", -+ "GPIOX_12", "GPIOX_13", "GPIOX_14", "GPIOX_15", -+ "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19"; -+ function = "gpio_periphs"; -+ bias-pull-up; -+ output-disable; -+ }; -+ }; -+}; -+ -+&pwm_ef { -+ status = "okay"; -+ pinctrl-0 = <&pwm_f_h_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&saradc { -+ status = "okay"; -+ vref-supply = <&vddio_ao1v8>; -+}; -+ -+/* SD card */ -+&sd_emmc_b { -+ status = "okay"; -+ pinctrl-0 = <&sdcard_c_pins>; -+ pinctrl-1 = <&sdcard_clk_gate_c_pins>; -+ pinctrl-names = "default", "clk-gate"; -+ -+ bus-width = <4>; -+ cap-sd-highspeed; -+ max-frequency = <50000000>; -+ disable-wp; -+ -+ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; -+ vmmc-supply = <&vcc_sd>; -+ vqmmc-supply = <&vddio_c>; -+ -+}; -+ -+/* eMMC */ -+&sd_emmc_c { -+ status = "okay"; -+ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; -+ pinctrl-1 = <&emmc_clk_gate_pins>; -+ pinctrl-names = "default", "clk-gate"; -+ -+ bus-width = <8>; -+ cap-mmc-highspeed; -+ mmc-ddr-1_8v; -+ mmc-hs200-1_8v; -+ max-frequency = <200000000>; -+ disable-wp; -+ -+ mmc-pwrseq = <&emmc_pwrseq>; -+ vmmc-supply = <&vcc_sd>; -+ vqmmc-supply = <&vddio_ao1v8>; -+}; -+ -+ -+&tdmif_b { -+ pinctrl-0 = <&mclk0_a_pins>, <&tdm_b_fs_pins>, <&tdm_b_sclk_pins>, -+ <&tdm_b_dout0_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ -+ assigned-clocks = <&clkc_audio AUD_CLKID_TDM_MCLK_PAD0>, -+ <&clkc_audio AUD_CLKID_TDM_SCLK_PAD1>, -+ <&clkc_audio AUD_CLKID_TDM_LRCLK_PAD1>; -+ assigned-clock-parents = <&clkc_audio AUD_CLKID_MST_B_MCLK>, -+ <&clkc_audio AUD_CLKID_MST_B_SCLK>, -+ <&clkc_audio AUD_CLKID_MST_B_LRCLK>; -+ assigned-clock-rates = <0>, <0>, <0>; -+}; -+ -+&tdmout_b { -+ status = "okay"; -+}; -+ -+&uart_AO { -+ status = "okay"; -+ pinctrl-0 = <&uart_ao_a_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&usb { -+ status = "okay"; -+ dr_mode = "peripheral"; -+}; -+ -+&usb2_phy0 { -+ status = "okay"; -+}; -+ -+&usb2_phy1 { -+ status = "okay"; -+ phy-supply = <&usb_host>; -+}; -diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts linux/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts ---- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts 1970-01-01 00:00:00.000000000 +0000 -+++ linux/arch/arm64/boot/dts/amlogic/meson-g12b-powkiddy-rgb10-max-3.dts 2023-09-12 12:04:13.567330573 +0000 -@@ -0,0 +1,995 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Copyright (c) 2022 Neil Armstrong -+ * Copyright (C) 2022-present - The JELOS Project (https://github.com/JustEnoughLinuxOS) -+ */ -+ -+/dts-v1/; -+ -+#include "meson-g12b-a311d.dtsi" -+#include -+#include -+#include -+#include -+#include -+ -+/ { -+ compatible = "powkiddy,rgb10-max-3", "amlogic,s922x", "amlogic,g12b"; -+ model = "Powkiddy RGB10 MAX 3"; -+ -+ aliases { -+ serial0 = &uart_AO; -+ rtc0 = &vrtc; -+ mmc0 = &sd_emmc_c; -+ mmc1 = &sd_emmc_b; -+ }; -+ -+ panel_backlight: backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&pwm_ef 1 40000 0>; -+ brightness-levels = <0 255>; -+ num-interpolated-steps = <255>; -+ default-brightness-level = <255>; -+ }; -+ -+ bat: battery { -+ compatible = "simple-battery"; -+ voltage-max-design-microvolt = <4200000>; -+ voltage-min-design-microvolt = <3500000>; -+ charge-full-design-microamp-hours = <4000000>; -+ charge-term-current-microamp = <200000>; -+ constant-charge-current-max-microamp = <1500000>; -+ constant-charge-voltage-max-microvolt = <4200000>; -+ factory-internal-resistance-micro-ohms = <180000>; -+ -+ -+ ocv-capacity-celsius = <20>; -+ ocv-capacity-table-0 = <4146950 100>, <4001920 95>, <3967900 90>, <3919950 85>, -+ <3888450 80>, <3861850 75>, <3831540 70>, <3799130 65>, -+ <3768190 60>, <3745650 55>, <3726610 50>, <3711630 45>, -+ <3696720 40>, <3685660 35>, <3674950 30>, <3663050 25>, -+ <3649470 20>, <3635260 15>, <3616920 10>, <3592440 5>, -+ <3574170 0>; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+ -+ codec_clk: codec-clk { -+ compatible = "fixed-clock"; -+ clock-frequency = <12288000>; -+ clock-output-names = "codec_clk"; -+ #clock-cells = <0>; -+ }; -+ -+ gpio_keys: volume-keys { -+ compatible = "gpio-keys-polled"; -+ poll-interval = <5>; -+ autorepeat; -+ -+ volume-up-button { -+ label = "VOLUME-UP"; -+ linux,code = ; -+ gpios = <&gpio GPIOX_8 GPIO_ACTIVE_LOW>; -+ }; -+ volume-down-button { -+ label = "VOLUME-DOWN"; -+ linux,code = ; -+ gpios = <&gpio GPIOX_9 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ joypad: gou_joypad { -+ compatible = "odroidgou-joypad"; -+ poll-interval = <10>; -+ pinctrl-0 = <&keypad_gpio_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ -+ joypad-name = "GO-Ultra Gamepad"; -+ //joypad-vendor = <0x045e>; -+ joypad-product = <0x1000>; -+ joypad-revision = <0x0100>; -+ -+ /* Analog sticks */ -+ -+ io-channels = <&saradc 0>, <&saradc 1>, <&saradc 2>, <&saradc 3>; -+ io-channel-names = "key-RY", "key-RX", "key-LY", "key-LX"; -+ button-adc-scale = <4>; -+ button-adc-deadzone = <400>; -+ button-adc-fuzz = <64>; -+ button-adc-flat = <32>; -+ abs_x-p-tuning = <350>; -+ abs_x-n-tuning = <350>; -+ abs_y-p-tuning = <350>; -+ abs_y-n-tuning = <350>; -+ abs_rx-p-tuning = <350>; -+ abs_rx-n-tuning = <350>; -+ abs_ry-p-tuning = <350>; -+ abs_ry-n-tuning = <350>; -+ -+ /* Buttons */ -+ sw1 { -+ gpios = <&gpio GPIOX_0 GPIO_ACTIVE_LOW>; -+ label = "GPIO DPAD-UP"; -+ linux,code = ; // 0x220 -+ }; -+ sw2 { -+ gpios = <&gpio GPIOX_1 GPIO_ACTIVE_LOW>; -+ label = "GPIO DPAD-DOWN"; -+ linux,code = ; // 0x221 -+ }; -+ sw3 { -+ gpios = <&gpio GPIOX_2 GPIO_ACTIVE_LOW>; -+ label = "GPIO DPAD-LEFT"; -+ linux,code = ; // 0x222 -+ }; -+ sw4 { -+ gpios = <&gpio GPIOX_3 GPIO_ACTIVE_LOW>; -+ label = "GPIO DPAD-RIGHT"; -+ linux,code = ; // 0x223 -+ }; -+ sw5 { -+ gpios = <&gpio GPIOX_4 GPIO_ACTIVE_LOW>; -+ label = "GPIO BTN-A"; -+ linux,code = ; // 0x131 -+ }; -+ sw6 { -+ gpios = <&gpio GPIOX_5 GPIO_ACTIVE_LOW>; -+ label = "GPIO BTN-B"; -+ linux,code = ; // 0x130 -+ }; -+ sw7 { -+ gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; -+ label = "GPIO BTN-Y"; -+ linux,code = ; // 0x134 -+ }; -+ sw8 { -+ gpios = <&gpio GPIOX_7 GPIO_ACTIVE_LOW>; -+ label = "GPIO BTN-X"; -+ linux,code = ; // 0x133 -+ }; -+ sw11 { -+ gpios = <&gpio GPIOX_10 GPIO_ACTIVE_LOW>; -+ label = "GPIO F2"; -+ linux,code = ; // 0x2c2 -+ }; -+ sw12 { -+ gpios = <&gpio GPIOX_17 GPIO_ACTIVE_LOW>; -+ label = "GPIO F3"; -+ linux,code = ; // 0x2c3 -+ }; -+ sw13 { -+ gpios = <&gpio GPIOX_16 GPIO_ACTIVE_LOW>; -+ label = "GPIO F4"; -+ linux,code = ; // 0x2c4 -+ }; -+ sw14 { -+ gpios = <&gpio GPIOX_11 GPIO_ACTIVE_LOW>; -+ label = "GPIO F5"; -+ linux,code = ; // 0x13c -+ }; -+ sw15 { -+ gpios = <&gpio GPIOX_14 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-LEFT"; -+ linux,code = ; // 0x02 -+ }; -+ sw16 { -+ gpios = <&gpio GPIOX_15 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-RIGHT"; -+ linux,code = ; // 0x05 -+ }; -+ sw17 { -+ gpios = <&gpio GPIOX_13 GPIO_ACTIVE_LOW>; -+ label = "GPIO F6"; -+ linux,code = ; -+ }; -+ sw18 { -+ gpios = <&gpio GPIOX_12 GPIO_ACTIVE_LOW>; -+ label = "GPIO F1"; -+ linux,code = ; -+ }; -+ sw19 { -+ gpios = <&gpio GPIOX_18 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-RIGHT2"; -+ linux,code = ; -+ }; -+ sw20 { -+ gpios = <&gpio GPIOX_19 GPIO_ACTIVE_LOW>; -+ label = "GPIO TOP-LEFT2"; -+ linux,code = ; -+ }; -+ }; -+ -+ memory@0 { -+ device_type = "memory"; -+ reg = <0x0 0x0 0x0 0x40000000>; -+ }; -+ -+ emmc_pwrseq: emmc-pwrseq { -+ compatible = "mmc-pwrseq-emmc"; -+ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ led-blue { -+ color = ; -+ function = LED_FUNCTION_STATUS; -+ gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "none"; -+ }; -+ -+ led-red { -+ color = ; -+ function = LED_FUNCTION_STATUS; -+ gpios = <&gpio_ao GPIOAO_6 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ -+ poweroff { -+ compatible = "hardkernel,odroid-go-ultra-poweroff"; -+ hardkernel,rk817-pmic = <&rk817>; -+ hardkernel,rk818-pmic = <&rk818>; -+ }; -+ -+ vdd_sys: regulator-vdd_sys { -+ compatible = "regulator-fixed"; -+ regulator-name = "VDD_SYS"; -+ regulator-min-microvolt = <3800000>; -+ regulator-max-microvolt = <3800000>; -+ regulator-always-on; -+ }; -+ -+ sound { -+ compatible = "amlogic,axg-sound-card"; -+ model = "RGB10-MAX3"; -+ audio-aux-devs = <&tdmout_b>; -+ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1", -+ "TDM_B Playback", "TDMOUT_B OUT"; -+ -+ assigned-clocks = <&clkc CLKID_MPLL2>, -+ <&clkc CLKID_MPLL0>, -+ <&clkc CLKID_MPLL1>; -+ assigned-clock-parents = <0>, <0>, <0>; -+ assigned-clock-rates = <294912000>, -+ <270950400>, -+ <393216000>; -+ status = "okay"; -+ -+ dai-link-0 { -+ sound-dai = <&frddr_a>; -+ }; -+ -+ dai-link-1 { -+ sound-dai = <&frddr_b>; -+ }; -+ -+ dai-link-2 { -+ sound-dai = <&frddr_c>; -+ }; -+ -+ dai-link-3 { -+ sound-dai = <&toddr_a>; -+ }; -+ -+ dai-link-4 { -+ sound-dai = <&toddr_b>; -+ }; -+ -+ dai-link-5 { -+ sound-dai = <&toddr_c>; -+ }; -+ -+ /* 8ch hdmi interface */ -+ dai-link-6 { -+ sound-dai = <&tdmif_b>; -+ dai-format = "i2s"; -+ dai-tdm-slot-tx-mask-0 = <1 1>; -+ dai-tdm-slot-tx-mask-1 = <1 1>; -+ mclk-fs = <256>; -+ -+ codec-0 { -+ sound-dai = <&rk817>; -+ }; -+ }; -+ }; -+}; -+ -+&arb { -+ status = "okay"; -+}; -+ -+&cpu0 { -+ cpu-supply = <&vddcpu_b>; -+ operating-points-v2 = <&cpu_opp_table_0>; -+ clocks = <&clkc CLKID_CPU_CLK>; -+ clock-latency = <50000>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&vddcpu_b>; -+ operating-points-v2 = <&cpu_opp_table_0>; -+ clocks = <&clkc CLKID_CPU_CLK>; -+ clock-latency = <50000>; -+}; -+ -+&cpu100 { -+ cpu-supply = <&vddcpu_a>; -+ operating-points-v2 = <&cpub_opp_table_1>; -+ clocks = <&clkc CLKID_CPUB_CLK>; -+ clock-latency = <50000>; -+}; -+ -+&cpu101 { -+ cpu-supply = <&vddcpu_a>; -+ operating-points-v2 = <&cpub_opp_table_1>; -+ clocks = <&clkc CLKID_CPUB_CLK>; -+ clock-latency = <50000>; -+}; -+ -+&cpu102 { -+ cpu-supply = <&vddcpu_a>; -+ operating-points-v2 = <&cpub_opp_table_1>; -+ clocks = <&clkc CLKID_CPUB_CLK>; -+ clock-latency = <50000>; -+}; -+ -+&cpu103 { -+ cpu-supply = <&vddcpu_a>; -+ operating-points-v2 = <&cpub_opp_table_1>; -+ clocks = <&clkc CLKID_CPUB_CLK>; -+ clock-latency = <50000>; -+}; -+ -+/* RK817 only supports 12.5mV steps, round up the values */ -+&cpu_opp_table_0 { -+ opp-667000000 { -+ opp-microvolt = <731250>; -+ }; -+ opp-1000000000 { -+ opp-microvolt = <760000>; -+ }; -+ opp-1200000000 { -+ opp-microvolt = <780000>; -+ }; -+ opp-1398000000 { -+ opp-microvolt = <800000>; -+ }; -+ opp-1512000000 { -+ opp-microvolt = <860000>; -+ }; -+ opp-1608000000 { -+ opp-microvolt = <900000>; -+ }; -+ opp-1704000000 { -+ opp-microvolt = <950000>; -+ }; -+ opp-1800000000 { -+ opp-microvolt = <1000000>; -+ }; -+}; -+ -+/* RK818 only supports 12.5mV steps, round up the values */ -+&cpub_opp_table_1 { -+ opp-667000000 { -+ opp-microvolt = <750000>; -+ }; -+ opp-1000000000 { -+ opp-microvolt = <775000>; -+ }; -+ opp-1200000000 { -+ opp-microvolt = <775000>; -+ }; -+ opp-1398000000 { -+ opp-microvolt = <800000>; -+ }; -+ opp-1512000000 { -+ opp-microvolt = <825000>; -+ }; -+ opp-1608000000 { -+ opp-microvolt = <862500>; -+ }; -+ opp-1704000000 { -+ opp-microvolt = <900000>; -+ }; -+ opp-1800000000 { -+ opp-microvolt = <987500>; -+ }; -+ opp-1908000000 { -+ opp-microvolt = <1025000>; -+ }; -+ opp-2016000000 { -+ opp-hz = /bits/ 64 <2016000000>; -+ opp-microvolt = <1025000>; -+ }; -+ opp-2100000000 { -+ opp-hz = /bits/ 64 <2100000000>; -+ opp-microvolt = <1025000>; -+ }; -+ opp-2208000000 { -+ opp-hz = /bits/ 64 <2208000000>; -+ opp-microvolt = <1050000>; -+ }; -+}; -+ -+&i2c_AO { -+ status = "okay"; -+ pinctrl-0 = <&i2c_ao_sck_pins>, <&i2c_ao_sda_pins>; -+ pinctrl-names = "default"; -+ -+ rk818: pmic@1c { -+ compatible = "rockchip,rk818"; -+ reg = <0x1c>; -+ interrupt-parent = <&gpio_intc>; -+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>; /* GPIOAO_7 */ -+ rockchip,system-power-controller; -+ clock-output-names = "rk808-clkout1", "rk808-clkout2"; -+ -+ vcc1-supply = <&vdd_sys>; -+ vcc2-supply = <&vdd_sys>; -+ vcc3-supply = <&vdd_sys>; -+ vcc4-supply = <&vdd_sys>; -+ vcc6-supply = <&vdd_sys>; -+ vcc7-supply = <&vcc_2v3>; -+ vcc8-supply = <&vcc_2v3>; -+ vcc9-supply = <&vddao_3v3>; -+ boost-supply = <&vdd_sys>; -+ switch-supply = <&vdd_sys>; -+ -+ regulators { -+ vddcpu_a: DCDC_REG1 { -+ regulator-name = "vddcpu_a"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1050000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <750000>; -+ }; -+ }; -+ -+ vdd_ee: DCDC_REG2 { -+ regulator-name = "vdd_ee"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <875000>; -+ regulator-max-microvolt = <900000>; -+ regulator-ramp-delay = <6001>; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <875000>; -+ }; -+ }; -+ -+ vddq_1v1: DCDC_REG3 { -+ regulator-name = "vddq_1v1"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ vddao_3v3: DCDC_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-name = "vddao_3v3"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3000000>; -+ }; -+ }; -+ -+ hp_5v: DCDC_BOOST { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-name = "hp_5v"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG1 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO1"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG2 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO2"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG3 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO3"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG4 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO4"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vddio_ao1v8: LDO_REG5 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vddio_ao1v8"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ LDO_REG6 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO6"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vddq_1v8: LDO_REG7 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-name = "vddq_1v8"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1800000>; -+ }; -+ }; -+ -+ LDO_REG8 { -+ regulator-boot-off; -+ regulator-name = "rk818_LDO8"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vddio_c: LDO_REG9 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vddio_c"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <3300000>; -+ }; -+ }; -+ -+ vcc_sd: SWITCH_REG { -+ regulator-name = "vcc_sd"; -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ rk818_otg_switch: OTG_SWITCH { -+ regulator-name = "otg_switch"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ -+ battery { -+ compatible = "rockchip,rk818-battery"; -+ -+ ocv_table = < -+ 3470 3599 3671 3701 3728 3746 3762 -+ 3772 3781 3792 3816 3836 3866 3910 -+ 3942 3971 4002 4050 4088 4132 4200>; -+ design_capacity = <4000>; -+ design_qmax = <4100>; -+ bat_res = <180>; -+ max_input_current = <2000>; -+ max_chrg_current = <1500>; -+ max_chrg_voltage = <4250>; -+ sleep_enter_current = <300>; -+ sleep_exit_current = <300>; -+ power_off_thresd = <3450>; -+ zero_algorithm_vol = <3700>; -+ fb_temperature = <105>; -+ sample_res = <10>; -+ max_soc_offset = <60>; -+ energy_mode = <0>; -+ monitor_sec = <5>; -+ virtual_power = <0>; -+ power_dc2otg = <0>; -+ otg5v_suspend_enable = <0>; -+ }; -+ -+ charger { -+ compatible = "rockchip,rk818-charger"; -+ monitored-battery = <&bat>; -+ }; -+ -+ }; -+}; -+ -+&i2c3 { -+ status = "okay"; -+ pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>; -+ pinctrl-names = "default"; -+ -+ rk817: pmic@20 { -+ compatible = "rockchip,rk817"; -+ reg = <0x20>; -+ status = "okay"; -+ interrupt-parent = <&gpio_intc>; -+ interrupts = <5 IRQ_TYPE_LEVEL_LOW>; /* GPIOAO_5 */ -+ wakeup-source; -+ -+ vcc1-supply = <&vdd_sys>; -+ vcc2-supply = <&vdd_sys>; -+ vcc3-supply = <&vdd_sys>; -+ vcc4-supply = <&vdd_sys>; -+ vcc5-supply = <&vdd_sys>; -+ vcc6-supply = <&vdd_sys>; -+ vcc7-supply = <&vdd_sys>; -+ vcc8-supply = <&vdd_sys>; -+ vcc9-supply = <&rk817_boost>; -+ -+ #sound-dai-cells = <0>; -+ clocks = <&codec_clk>; -+ clock-names = "mclk"; -+ -+ regulators { -+ DCDC_REG1 { -+ regulator-boot-off; -+ regulator-name = "rk817_BUCK1"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vddcpu_b: DCDC_REG2 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <725000>; -+ regulator-max-microvolt = <1050000>; -+ regulator-ramp-delay = <6001>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vddcpu_b"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1000000>; -+ }; -+ }; -+ -+ vcc_2v3: DCDC_REG3 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <2300000>; -+ regulator-max-microvolt = <2400000>; -+ regulator-initial-mode = <0x2>; -+ regulator-name = "vcc_2v3"; -+ regulator-state-mem { -+ regulator-on-in-suspend; -+ }; -+ }; -+ -+ DCDC_REG4 { -+ regulator-boot-off; -+ regulator-name = "rk817_BUCK4"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG1 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO1"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG2 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO2"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG3 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO3"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG4 { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vdd_codec"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG5 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO5"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG6 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO6"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG7 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO7"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ vcc_lcd: LDO_REG8 { -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-name = "vcc_lcd"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ LDO_REG9 { -+ regulator-boot-off; -+ regulator-name = "rk817_LDO9"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ rk817_boost: BOOST { -+ regulator-always-on; -+ regulator-boot-on; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5400000>; -+ regulator-name = "rk817_boost"; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ -+ usb_host: OTG_SWITCH { -+ regulator-name = "usb_host"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-state-mem { -+ regulator-off-in-suspend; -+ }; -+ }; -+ }; -+ -+ rk817_codec: codec { -+ rockchip,mic-in-differential; -+ }; -+ }; -+}; -+ -+&clkc_audio { -+ status = "okay"; -+}; -+ -+ð_phy { -+ status = "disabled"; -+}; -+ -+&frddr_a { -+ status = "okay"; -+}; -+ -+&frddr_b { -+ status = "okay"; -+}; -+ -+&frddr_c { -+ status = "okay"; -+}; -+ -+&toddr_a { -+ status = "okay"; -+}; -+ -+&toddr_b { -+ status = "okay"; -+}; -+ -+&toddr_c { -+ status = "okay"; -+}; -+ -+&mipi_dsi { -+ status = "okay"; -+ -+ assigned-clocks = <&clkc CLKID_GP0_PLL>, -+ <&clkc CLKID_MIPI_DSI_PXCLK_SEL>, -+ <&clkc CLKID_MIPI_DSI_PXCLK>, -+ <&clkc CLKID_CTS_ENCL_SEL>, -+ <&clkc CLKID_VCLK2_SEL>; -+ assigned-clock-parents = <0>, -+ <&clkc CLKID_GP0_PLL>, -+ <0>, -+ <&clkc CLKID_VCLK2_DIV1>, -+ <&clkc CLKID_GP0_PLL>; -+ assigned-clock-rates = <344976000>, -+ <0>, -+ <344976000>, -+ <0>, -+ <0>; -+ -+ panel@0 { -+ compatible = "elida,kd50t048a", "sitronix,st7701"; -+ reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_HIGH>; -+ IOVCC-supply = <&vcc_lcd>; -+ VCC-supply = <&vcc_lcd>; -+ backlight = <&panel_backlight>; -+ rotation = <270>; -+ reg = <0>; -+ -+ port { -+ mipi_in_panel: endpoint { -+ remote-endpoint = <&mipi_out_panel>; -+ }; -+ }; -+ }; -+}; -+ -+&mipi_analog_dphy { -+ status = "okay"; -+}; -+ -+&mipi_dphy { -+ status = "okay"; -+}; -+ -+&mipi_dsi_panel_port { -+ mipi_out_panel: endpoint { -+ remote-endpoint = <&mipi_in_panel>; -+ }; -+}; -+ -+&periphs_pinctrl { -+ keypad_gpio_pins: keypad-gpio { -+ mux { -+ groups = "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", -+ "GPIOX_4", "GPIOX_5", "GPIOX_6", "GPIOX_7", -+ "GPIOX_8", "GPIOX_9", "GPIOX_10", "GPIOX_11", -+ "GPIOX_12", "GPIOX_13", "GPIOX_14", "GPIOX_15", -+ "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19"; -+ function = "gpio_periphs"; -+ bias-pull-up; -+ output-disable; -+ }; -+ }; -+}; -+ -+&pwm_ef { -+ status = "okay"; -+ pinctrl-0 = <&pwm_f_h_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&saradc { -+ status = "okay"; -+ vref-supply = <&vddio_ao1v8>; -+}; -+ -+/* SD card */ -+&sd_emmc_b { -+ status = "okay"; -+ pinctrl-0 = <&sdcard_c_pins>; -+ pinctrl-1 = <&sdcard_clk_gate_c_pins>; -+ pinctrl-names = "default", "clk-gate"; -+ -+ bus-width = <4>; -+ cap-sd-highspeed; -+ max-frequency = <50000000>; -+ disable-wp; -+ -+ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>; -+ vmmc-supply = <&vcc_sd>; -+ vqmmc-supply = <&vddio_c>; -+ -+}; -+ -+/* eMMC */ -+&sd_emmc_c { -+ status = "okay"; -+ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>; -+ pinctrl-1 = <&emmc_clk_gate_pins>; -+ pinctrl-names = "default", "clk-gate"; -+ -+ bus-width = <8>; -+ cap-mmc-highspeed; -+ mmc-ddr-1_8v; -+ mmc-hs200-1_8v; -+ max-frequency = <200000000>; -+ disable-wp; -+ -+ mmc-pwrseq = <&emmc_pwrseq>; -+ vmmc-supply = <&vcc_sd>; -+ vqmmc-supply = <&vddio_ao1v8>; -+}; -+ -+ -+&tdmif_b { -+ pinctrl-0 = <&mclk0_a_pins>, <&tdm_b_fs_pins>, <&tdm_b_sclk_pins>, -+ <&tdm_b_dout0_pins>; -+ pinctrl-names = "default"; -+ status = "okay"; -+ -+ assigned-clocks = <&clkc_audio AUD_CLKID_TDM_MCLK_PAD0>, -+ <&clkc_audio AUD_CLKID_TDM_SCLK_PAD1>, -+ <&clkc_audio AUD_CLKID_TDM_LRCLK_PAD1>; -+ assigned-clock-parents = <&clkc_audio AUD_CLKID_MST_B_MCLK>, -+ <&clkc_audio AUD_CLKID_MST_B_SCLK>, -+ <&clkc_audio AUD_CLKID_MST_B_LRCLK>; -+ assigned-clock-rates = <0>, <0>, <0>; -+}; -+ -+&tdmout_b { -+ status = "okay"; -+}; -+ -+&uart_AO { -+ status = "okay"; -+ pinctrl-0 = <&uart_ao_a_pins>; -+ pinctrl-names = "default"; -+}; -+ -+&usb { -+ status = "okay"; -+ dr_mode = "peripheral"; -+}; -+ -+&usb2_phy0 { -+ status = "okay"; -+}; -+ -+&usb2_phy1 { -+ status = "okay"; -+ phy-supply = <&usb_host>; -+}; -diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi ---- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi 2023-09-12 12:02:56.937601871 +0000 -+++ linux/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi 2023-09-12 12:03:27.490291628 +0000 -@@ -11,6 +11,11 @@ - compatible = "operating-points-v2"; - opp-shared; - -+ opp-667000000 { -+ opp-hz = /bits/ 64 <667000000>; -+ opp-microvolt = <731000>; -+ }; -+ - opp-1000000000 { - opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <731000>; -@@ -56,6 +61,11 @@ - compatible = "operating-points-v2"; - opp-shared; - -+ opp-667000000 { -+ opp-hz = /bits/ 64 <667000000>; -+ opp-microvolt = <751000>; -+ }; -+ - opp-1000000000 { - opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <771000>; -diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi ---- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi 2023-09-12 12:02:56.937601871 +0000 -+++ linux/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi 2023-09-12 12:03:27.490291628 +0000 -@@ -105,6 +105,8 @@ - - l2: l2-cache0 { - compatible = "cache"; -+ cache-level = <2>; -+ cache-unified; - }; - }; - }; -@@ -137,5 +139,6 @@ - }; - - &mali { -- dma-coherent; -+ system-coherency = <0>; -+ power_policy = "always_on"; - }; -diff -rupN linux.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c linux/drivers/gpu/drm/drm_panel_orientation_quirks.c ---- linux.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-09-12 12:02:57.953624819 +0000 -+++ linux/drivers/gpu/drm/drm_panel_orientation_quirks.c 2023-09-12 12:03:27.490291628 +0000 -@@ -461,7 +461,7 @@ EXPORT_SYMBOL(drm_get_panel_orientation_ - /* There are no quirks for non x86 devices yet */ - int drm_get_panel_orientation_quirk(int width, int height) - { -- return DRM_MODE_PANEL_ORIENTATION_UNKNOWN; -+ return DRM_MODE_PANEL_ORIENTATION_LEFT_UP; - } - EXPORT_SYMBOL(drm_get_panel_orientation_quirk); - -diff -rupN linux.orig/drivers/input/Kconfig linux/drivers/input/Kconfig ---- linux.orig/drivers/input/Kconfig 2023-09-12 12:02:58.173629790 +0000 -+++ linux/drivers/input/Kconfig 2023-09-12 12:03:27.490291628 +0000 -@@ -51,6 +51,19 @@ config INPUT_FF_MEMLESS - To compile this driver as a module, choose M here: the - module will be called ff-memless. - -+config INPUT_POLLDEV -+ tristate "Polled input device skeleton" -+ help -+ Say Y here if you are using a driver for an input -+ device that periodically polls hardware state. This -+ option is only useful for out-of-tree drivers since -+ in-tree drivers select it automatically. -+ -+ If unsure, say N. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called input-polldev. -+ - config INPUT_SPARSEKMAP - tristate "Sparse keymap support library" - help -diff -rupN linux.orig/drivers/input/Makefile linux/drivers/input/Makefile ---- linux.orig/drivers/input/Makefile 2023-09-12 12:02:58.173629790 +0000 -+++ linux/drivers/input/Makefile 2023-09-12 12:03:27.490291628 +0000 -@@ -10,6 +10,7 @@ input-core-y := input.o input-compat.o i - input-core-y += touchscreen.o - - obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o -+obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o - obj-$(CONFIG_INPUT_SPARSEKMAP) += sparse-keymap.o - obj-$(CONFIG_INPUT_MATRIXKMAP) += matrix-keymap.o - obj-$(CONFIG_INPUT_VIVALDIFMAP) += vivaldi-fmap.o -diff -rupN linux.orig/drivers/input/input-polldev.c linux/drivers/input/input-polldev.c ---- linux.orig/drivers/input/input-polldev.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux/drivers/input/input-polldev.c 2023-09-12 12:03:27.490291628 +0000 -@@ -0,0 +1,362 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Generic implementation of a polled input device -+ -+ * Copyright (c) 2007 Dmitry Torokhov -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+MODULE_AUTHOR("Dmitry Torokhov "); -+MODULE_DESCRIPTION("Generic implementation of a polled input device"); -+MODULE_LICENSE("GPL v2"); -+ -+static void input_polldev_queue_work(struct input_polled_dev *dev) -+{ -+ unsigned long delay; -+ -+ delay = msecs_to_jiffies(dev->poll_interval); -+ if (delay >= HZ) -+ delay = round_jiffies_relative(delay); -+ -+ queue_delayed_work(system_freezable_wq, &dev->work, delay); -+} -+ -+static void input_polled_device_work(struct work_struct *work) -+{ -+ struct input_polled_dev *dev = -+ container_of(work, struct input_polled_dev, work.work); -+ -+ dev->poll(dev); -+ input_polldev_queue_work(dev); -+} -+ -+static int input_open_polled_device(struct input_dev *input) -+{ -+ struct input_polled_dev *dev = input_get_drvdata(input); -+ -+ if (dev->open) -+ dev->open(dev); -+ -+ /* Only start polling if polling is enabled */ -+ if (dev->poll_interval > 0) { -+ dev->poll(dev); -+ input_polldev_queue_work(dev); -+ } -+ -+ return 0; -+} -+ -+static void input_close_polled_device(struct input_dev *input) -+{ -+ struct input_polled_dev *dev = input_get_drvdata(input); -+ -+ cancel_delayed_work_sync(&dev->work); -+ -+ if (dev->close) -+ dev->close(dev); -+} -+ -+/* SYSFS interface */ -+ -+static ssize_t input_polldev_get_poll(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct input_polled_dev *polldev = dev_get_drvdata(dev); -+ -+ return sprintf(buf, "%d\n", polldev->poll_interval); -+} -+ -+static ssize_t input_polldev_set_poll(struct device *dev, -+ struct device_attribute *attr, const char *buf, -+ size_t count) -+{ -+ struct input_polled_dev *polldev = dev_get_drvdata(dev); -+ struct input_dev *input = polldev->input; -+ unsigned int interval; -+ int err; -+ -+ err = kstrtouint(buf, 0, &interval); -+ if (err) -+ return err; -+ -+ if (interval < polldev->poll_interval_min) -+ return -EINVAL; -+ -+ if (interval > polldev->poll_interval_max) -+ return -EINVAL; -+ -+ mutex_lock(&input->mutex); -+ -+ polldev->poll_interval = interval; -+ -+ if (input->users) { -+ cancel_delayed_work_sync(&polldev->work); -+ if (polldev->poll_interval > 0) -+ input_polldev_queue_work(polldev); -+ } -+ -+ mutex_unlock(&input->mutex); -+ -+ return count; -+} -+ -+static DEVICE_ATTR(poll, S_IRUGO | S_IWUSR, input_polldev_get_poll, -+ input_polldev_set_poll); -+ -+ -+static ssize_t input_polldev_get_max(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct input_polled_dev *polldev = dev_get_drvdata(dev); -+ -+ return sprintf(buf, "%d\n", polldev->poll_interval_max); -+} -+ -+static DEVICE_ATTR(max, S_IRUGO, input_polldev_get_max, NULL); -+ -+static ssize_t input_polldev_get_min(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct input_polled_dev *polldev = dev_get_drvdata(dev); -+ -+ return sprintf(buf, "%d\n", polldev->poll_interval_min); -+} -+ -+static DEVICE_ATTR(min, S_IRUGO, input_polldev_get_min, NULL); -+ -+static struct attribute *sysfs_attrs[] = { -+ &dev_attr_poll.attr, -+ &dev_attr_max.attr, -+ &dev_attr_min.attr, -+ NULL -+}; -+ -+static struct attribute_group input_polldev_attribute_group = { -+ .attrs = sysfs_attrs -+}; -+ -+static const struct attribute_group *input_polldev_attribute_groups[] = { -+ &input_polldev_attribute_group, -+ NULL -+}; -+ -+/** -+ * input_allocate_polled_device - allocate memory for polled device -+ * -+ * The function allocates memory for a polled device and also -+ * for an input device associated with this polled device. -+ */ -+struct input_polled_dev *input_allocate_polled_device(void) -+{ -+ struct input_polled_dev *dev; -+ -+ dev = kzalloc(sizeof(struct input_polled_dev), GFP_KERNEL); -+ if (!dev) -+ return NULL; -+ -+ dev->input = input_allocate_device(); -+ if (!dev->input) { -+ kfree(dev); -+ return NULL; -+ } -+ -+ return dev; -+} -+EXPORT_SYMBOL(input_allocate_polled_device); -+ -+struct input_polled_devres { -+ struct input_polled_dev *polldev; -+}; -+ -+static int devm_input_polldev_match(struct device *dev, void *res, void *data) -+{ -+ struct input_polled_devres *devres = res; -+ -+ return devres->polldev == data; -+} -+ -+static void devm_input_polldev_release(struct device *dev, void *res) -+{ -+ struct input_polled_devres *devres = res; -+ struct input_polled_dev *polldev = devres->polldev; -+ -+ dev_dbg(dev, "%s: dropping reference/freeing %s\n", -+ __func__, dev_name(&polldev->input->dev)); -+ -+ input_put_device(polldev->input); -+ kfree(polldev); -+} -+ -+static void devm_input_polldev_unregister(struct device *dev, void *res) -+{ -+ struct input_polled_devres *devres = res; -+ struct input_polled_dev *polldev = devres->polldev; -+ -+ dev_dbg(dev, "%s: unregistering device %s\n", -+ __func__, dev_name(&polldev->input->dev)); -+ input_unregister_device(polldev->input); -+ -+ /* -+ * Note that we are still holding extra reference to the input -+ * device so it will stick around until devm_input_polldev_release() -+ * is called. -+ */ -+} -+ -+/** -+ * devm_input_allocate_polled_device - allocate managed polled device -+ * @dev: device owning the polled device being created -+ * -+ * Returns prepared &struct input_polled_dev or %NULL. -+ * -+ * Managed polled input devices do not need to be explicitly unregistered -+ * or freed as it will be done automatically when owner device unbinds -+ * from * its driver (or binding fails). Once such managed polled device -+ * is allocated, it is ready to be set up and registered in the same -+ * fashion as regular polled input devices (using -+ * input_register_polled_device() function). -+ * -+ * If you want to manually unregister and free such managed polled devices, -+ * it can be still done by calling input_unregister_polled_device() and -+ * input_free_polled_device(), although it is rarely needed. -+ * -+ * NOTE: the owner device is set up as parent of input device and users -+ * should not override it. -+ */ -+struct input_polled_dev *devm_input_allocate_polled_device(struct device *dev) -+{ -+ struct input_polled_dev *polldev; -+ struct input_polled_devres *devres; -+ -+ devres = devres_alloc(devm_input_polldev_release, sizeof(*devres), -+ GFP_KERNEL); -+ if (!devres) -+ return NULL; -+ -+ polldev = input_allocate_polled_device(); -+ if (!polldev) { -+ devres_free(devres); -+ return NULL; -+ } -+ -+ polldev->input->dev.parent = dev; -+ polldev->devres_managed = true; -+ -+ devres->polldev = polldev; -+ devres_add(dev, devres); -+ -+ return polldev; -+} -+EXPORT_SYMBOL(devm_input_allocate_polled_device); -+ -+/** -+ * input_free_polled_device - free memory allocated for polled device -+ * @dev: device to free -+ * -+ * The function frees memory allocated for polling device and drops -+ * reference to the associated input device. -+ */ -+void input_free_polled_device(struct input_polled_dev *dev) -+{ -+ if (dev) { -+ if (dev->devres_managed) -+ WARN_ON(devres_destroy(dev->input->dev.parent, -+ devm_input_polldev_release, -+ devm_input_polldev_match, -+ dev)); -+ input_put_device(dev->input); -+ kfree(dev); -+ } -+} -+EXPORT_SYMBOL(input_free_polled_device); -+ -+/** -+ * input_register_polled_device - register polled device -+ * @dev: device to register -+ * -+ * The function registers previously initialized polled input device -+ * with input layer. The device should be allocated with call to -+ * input_allocate_polled_device(). Callers should also set up poll() -+ * method and set up capabilities (id, name, phys, bits) of the -+ * corresponding input_dev structure. -+ */ -+int input_register_polled_device(struct input_polled_dev *dev) -+{ -+ struct input_polled_devres *devres = NULL; -+ struct input_dev *input = dev->input; -+ int error; -+ -+ if (dev->devres_managed) { -+ devres = devres_alloc(devm_input_polldev_unregister, -+ sizeof(*devres), GFP_KERNEL); -+ if (!devres) -+ return -ENOMEM; -+ -+ devres->polldev = dev; -+ } -+ -+ input_set_drvdata(input, dev); -+ INIT_DELAYED_WORK(&dev->work, input_polled_device_work); -+ -+ if (!dev->poll_interval) -+ dev->poll_interval = 500; -+ if (!dev->poll_interval_max) -+ dev->poll_interval_max = dev->poll_interval; -+ -+ input->open = input_open_polled_device; -+ input->close = input_close_polled_device; -+ -+ input->dev.groups = input_polldev_attribute_groups; -+ -+ error = input_register_device(input); -+ if (error) { -+ devres_free(devres); -+ return error; -+ } -+ -+ /* -+ * Take extra reference to the underlying input device so -+ * that it survives call to input_unregister_polled_device() -+ * and is deleted only after input_free_polled_device() -+ * has been invoked. This is needed to ease task of freeing -+ * sparse keymaps. -+ */ -+ input_get_device(input); -+ -+ if (dev->devres_managed) { -+ dev_dbg(input->dev.parent, "%s: registering %s with devres.\n", -+ __func__, dev_name(&input->dev)); -+ devres_add(input->dev.parent, devres); -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(input_register_polled_device); -+ -+/** -+ * input_unregister_polled_device - unregister polled device -+ * @dev: device to unregister -+ * -+ * The function unregisters previously registered polled input -+ * device from input layer. Polling is stopped and device is -+ * ready to be freed with call to input_free_polled_device(). -+ */ -+void input_unregister_polled_device(struct input_polled_dev *dev) -+{ -+ if (dev->devres_managed) -+ WARN_ON(devres_destroy(dev->input->dev.parent, -+ devm_input_polldev_unregister, -+ devm_input_polldev_match, -+ dev)); -+ -+ input_unregister_device(dev->input); -+} -+EXPORT_SYMBOL(input_unregister_polled_device); -diff -rupN linux.orig/drivers/input/joystick/Kconfig linux/drivers/input/joystick/Kconfig ---- linux.orig/drivers/input/joystick/Kconfig 2023-09-12 12:02:58.173629790 +0000 -+++ linux/drivers/input/joystick/Kconfig 2023-09-12 12:03:27.490291628 +0000 -@@ -344,6 +344,12 @@ config JOYSTICK_MAPLE - To compile this as a module choose M here: the module will be called - maplecontrol. - -+config JOYSTICK_ODROID_GOU -+ tristate "ODROID-Go-Ultra joypad driver" -+ depends on INPUT_POLLDEV -+ help -+ Made for ODROID-GO-Ultra. -+ - config JOYSTICK_PSXPAD_SPI - tristate "PlayStation 1/2 joypads via SPI interface" - depends on SPI -diff -rupN linux.orig/drivers/input/joystick/Makefile linux/drivers/input/joystick/Makefile ---- linux.orig/drivers/input/joystick/Makefile 2023-09-12 12:02:58.173629790 +0000 -+++ linux/drivers/input/joystick/Makefile 2023-09-12 12:03:27.490291628 +0000 -@@ -25,6 +25,7 @@ obj-$(CONFIG_JOYSTICK_JOYDUMP) += joydu - obj-$(CONFIG_JOYSTICK_MAGELLAN) += magellan.o - obj-$(CONFIG_JOYSTICK_MAPLE) += maplecontrol.o - obj-$(CONFIG_JOYSTICK_N64) += n64joy.o -+obj-$(CONFIG_JOYSTICK_ODROID_GOU) += odroid-gou-joypad.o - obj-$(CONFIG_JOYSTICK_PSXPAD_SPI) += psxpad-spi.o - obj-$(CONFIG_JOYSTICK_PXRC) += pxrc.o - obj-$(CONFIG_JOYSTICK_QWIIC) += qwiic-joystick.o -diff -rupN linux.orig/drivers/input/joystick/amlogic-saradc.h linux/drivers/input/joystick/amlogic-saradc.h ---- linux.orig/drivers/input/joystick/amlogic-saradc.h 1970-01-01 00:00:00.000000000 +0000 -+++ linux/drivers/input/joystick/amlogic-saradc.h 2023-09-12 12:03:27.490291628 +0000 -@@ -0,0 +1,32 @@ -+/* -+ * include/dt-bindings/iio/adc/amlogic-saradc.h -+ * -+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ */ -+ -+#ifndef _DT_BINDINGS_IIO_ADC_AMLOGIC_H -+#define _DT_BINDINGS_IIO_ADC_AMLOGIC_H -+ -+#define SARADC_CH0 0 -+#define SARADC_CH1 1 -+#define SARADC_CH2 2 -+#define SARADC_CH3 3 -+#define SARADC_CH4 4 -+#define SARADC_CH5 5 -+#define SARADC_CH6 6 -+#define SARADC_CH7 7 -+ -+#define SARADC_CH_NUM 8 -+ -+#endif -diff -rupN linux.orig/drivers/input/joystick/odroid-gou-joypad.c linux/drivers/input/joystick/odroid-gou-joypad.c ---- linux.orig/drivers/input/joystick/odroid-gou-joypad.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux/drivers/input/joystick/odroid-gou-joypad.c 2023-09-12 12:03:27.490291628 +0000 -@@ -0,0 +1,960 @@ -+/*----------------------------------------------------------------------------*/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "amlogic-saradc.h" -+#include -+ -+/*----------------------------------------------------------------------------*/ -+#define DRV_NAME "odroidgo_joypad" -+ -+/*----------------------------------------------------------------------------*/ -+ -+ -+/*----------------------------------------------------------------------------*/ -+#define ADC_MAX_VOLTAGE 1800 -+#define ADC_DATA_TUNING(x, p) ((x * p) / 100) -+#define ADC_TUNING_DEFAULT 180 -+ -+struct bt_adc { -+ /* report value (mV) */ -+ int value; -+ /* report type */ -+ int report_type; -+ /* input device init value (mV) */ -+ int max, min; -+ /* calibrated adc value */ -+ int cal; -+ /* adc scale value */ -+ int scale; -+ /* invert report */ -+ bool invert; -+ /* adc channel */ -+ int channel; -+ /* adc data tuning value([percent), p = positive, n = negative */ -+ int tuning_p, tuning_n; -+}; -+ -+struct bt_gpio { -+ /* GPIO Request label */ -+ const char *label; -+ /* GPIO Number */ -+ int num; -+ /* report type */ -+ int report_type; -+ /* report linux code */ -+ int linux_code; -+ /* prev button value */ -+ bool old_value; -+ /* button press level */ -+ bool active_level; -+}; -+ -+struct joypad { -+ struct device *dev; -+ struct input_polled_dev *poll_dev; -+ int poll_interval; -+ -+ /* report enable/disable */ -+ bool enable; -+ -+ /* analog mux & joystick control */ -+ struct iio_channel *adc_ch[SARADC_CH_NUM]; -+ -+ /* adc input channel count */ -+ int chan_count; -+ /* analog button */ -+ struct bt_adc *adcs; -+ -+ /* report interval (ms) */ -+ int bt_gpio_count; -+ struct bt_gpio *gpios; -+ -+ /* button auto repeat */ -+ int auto_repeat; -+ -+ /* report threshold (mV) */ -+ int bt_adc_fuzz, bt_adc_flat; -+ /* adc read value scale */ -+ int bt_adc_scale; -+ /* joystick deadzone control */ -+ int bt_adc_deadzone; -+ -+ struct mutex lock; -+ -+ /* adc debug channel */ -+ int debug_ch; -+}; -+ -+/*----------------------------------------------------------------------------*/ -+// -+// set to the value in the boot.ini file. (if exist) -+// -+/*----------------------------------------------------------------------------*/ -+static unsigned int g_button_adc_fuzz = 0; -+static unsigned int g_button_adc_flat = 0; -+static unsigned int g_button_adc_scale = 0; -+static unsigned int g_button_adc_deadzone = 0; -+ -+static int button_adc_fuzz(char *str) -+{ -+ if (!str) -+ return -EINVAL; -+ g_button_adc_fuzz = simple_strtoul(str, NULL, 10); -+ return 0; -+} -+__setup("button-adc-fuzz=", button_adc_fuzz); -+ -+static int button_adc_flat(char *str) -+{ -+ if (!str) -+ return -EINVAL; -+ g_button_adc_flat = simple_strtoul(str, NULL, 10); -+ return 0; -+} -+__setup("button-adc-flat=", button_adc_flat); -+ -+static int button_adc_scale(char *str) -+{ -+ if (!str) -+ return -EINVAL; -+ g_button_adc_scale = simple_strtoul(str, NULL, 10); -+ return 0; -+} -+__setup("button-adc-scale=", button_adc_scale); -+ -+static int button_adc_deadzone(char *str) -+{ -+ if (!str) -+ return -EINVAL; -+ g_button_adc_deadzone = simple_strtoul(str, NULL, 10); -+ return 0; -+} -+__setup("button-adc-deadzone=", button_adc_deadzone); -+ -+/*----------------------------------------------------------------------------*/ -+static int joypad_adc_read(struct joypad *joypad, struct bt_adc *adc) -+{ -+ int value; -+ -+ if (iio_read_channel_processed(joypad->adc_ch[adc->channel], &value) < 0) -+ return 0; -+ -+ value *= adc->scale; -+ -+ return (adc->invert ? (adc->max - value) : value); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/* -+ * ATTRIBUTES: -+ * -+ * /sys/devices/platform/odroidgo_joypad/poll_interval [rw] -+ */ -+/*----------------------------------------------------------------------------*/ -+static ssize_t joypad_store_poll_interval(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, -+ size_t count) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct joypad *joypad = platform_get_drvdata(pdev); -+ -+ mutex_lock(&joypad->lock); -+ joypad->poll_interval = simple_strtoul(buf, NULL, 10); -+ mutex_unlock(&joypad->lock); -+ -+ return count; -+} -+ -+/*----------------------------------------------------------------------------*/ -+static ssize_t joypad_show_poll_interval(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct joypad *joypad = platform_get_drvdata(pdev); -+ -+ return sprintf(buf, "%d\n", joypad->poll_interval); -+} -+ -+/*----------------------------------------------------------------------------*/ -+static DEVICE_ATTR(poll_interval, S_IWUSR | S_IRUGO, -+ joypad_show_poll_interval, -+ joypad_store_poll_interval); -+ -+/*----------------------------------------------------------------------------*/ -+/* -+ * ATTRIBUTES: -+ * -+ * /sys/devices/platform/odroidgo_joypad/adc_fuzz [r] -+ */ -+/*----------------------------------------------------------------------------*/ -+static ssize_t joypad_show_adc_fuzz(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct joypad *joypad = platform_get_drvdata(pdev); -+ -+ return sprintf(buf, "%d\n", joypad->bt_adc_fuzz); -+} -+ -+/*----------------------------------------------------------------------------*/ -+static DEVICE_ATTR(adc_fuzz, S_IWUSR | S_IRUGO, -+ joypad_show_adc_fuzz, -+ NULL); -+ -+/*----------------------------------------------------------------------------*/ -+/* -+ * ATTRIBUTES: -+ * -+ * /sys/devices/platform/odroidgo_joypad/adc_flat [r] -+ */ -+/*----------------------------------------------------------------------------*/ -+static ssize_t joypad_show_adc_flat(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct joypad *joypad = platform_get_drvdata(pdev); -+ -+ return sprintf(buf, "%d\n", joypad->bt_adc_flat); -+} -+ -+/*----------------------------------------------------------------------------*/ -+static DEVICE_ATTR(adc_flat, S_IWUSR | S_IRUGO, -+ joypad_show_adc_flat, -+ NULL); -+ -+/*----------------------------------------------------------------------------*/ -+/* -+ * ATTRIBUTES: -+ * -+ * /sys/devices/platform/oodroidgo_joypad/enable [rw] -+ */ -+/*----------------------------------------------------------------------------*/ -+static ssize_t joypad_store_enable(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, -+ size_t count) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct joypad *joypad = platform_get_drvdata(pdev); -+ -+ mutex_lock(&joypad->lock); -+ joypad->enable = simple_strtoul(buf, NULL, 10); -+ mutex_unlock(&joypad->lock); -+ -+ return count; -+} -+ -+/*----------------------------------------------------------------------------*/ -+static ssize_t joypad_show_enable(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct joypad *joypad = platform_get_drvdata(pdev); -+ -+ return sprintf(buf, "%d\n", joypad->enable); -+} -+ -+/*----------------------------------------------------------------------------*/ -+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, -+ joypad_show_enable, -+ joypad_store_enable); -+ -+/*----------------------------------------------------------------------------*/ -+/* -+ * ATTRIBUTES: -+ * -+ * /sys/devices/platform/odroidgo_joypad/adc_cal [rw] -+ */ -+/*----------------------------------------------------------------------------*/ -+static ssize_t joypad_store_adc_cal(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, -+ size_t count) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct joypad *joypad = platform_get_drvdata(pdev); -+ bool calibration; -+ -+ calibration = simple_strtoul(buf, NULL, 10); -+ -+ if (calibration) { -+ int nbtn; -+ -+ mutex_lock(&joypad->lock); -+ for (nbtn = 0; nbtn < joypad->chan_count; nbtn++) { -+ struct bt_adc *adc = &joypad->adcs[nbtn]; -+ -+ adc->value = joypad_adc_read(joypad, adc); -+ if (!adc->value) { -+ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", -+ __func__, nbtn); -+ continue; -+ } -+ adc->cal = adc->value; -+ } -+ mutex_unlock(&joypad->lock); -+ } -+ return count; -+} -+ -+/*----------------------------------------------------------------------------*/ -+static ssize_t joypad_show_adc_cal(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct joypad *joypad = platform_get_drvdata(pdev); -+ int nbtn; -+ ssize_t pos; -+ -+ for (nbtn = 0, pos = 0; nbtn < joypad->chan_count; nbtn++) { -+ struct bt_adc *adc = &joypad->adcs[nbtn]; -+ pos += sprintf(&buf[pos], "adc[%d]->cal = %d\n", -+ nbtn, adc->cal); -+ } -+ pos += sprintf(&buf[pos], "adc scale = %d\n", joypad->bt_adc_scale); -+ return pos; -+} -+ -+/*----------------------------------------------------------------------------*/ -+static DEVICE_ATTR(adc_cal, S_IWUSR | S_IRUGO, -+ joypad_show_adc_cal, -+ joypad_store_adc_cal); -+ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+static struct attribute *joypad_attrs[] = { -+ &dev_attr_poll_interval.attr, -+ &dev_attr_adc_fuzz.attr, -+ &dev_attr_adc_flat.attr, -+ &dev_attr_enable.attr, -+ &dev_attr_adc_cal.attr, -+ NULL, -+}; -+ -+static struct attribute_group joypad_attr_group = { -+ .attrs = joypad_attrs, -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+static void joypad_gpio_check(struct input_polled_dev *poll_dev) -+{ -+ struct joypad *joypad = poll_dev->private; -+ int nbtn, value; -+ -+ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { -+ struct bt_gpio *gpio = &joypad->gpios[nbtn]; -+ -+ if (gpio_get_value_cansleep(gpio->num) < 0) { -+ dev_err(joypad->dev, "failed to get gpio state\n"); -+ continue; -+ } -+ value = gpio_get_value(gpio->num); -+ if (value != gpio->old_value) { -+ input_event(poll_dev->input, -+ gpio->report_type, -+ gpio->linux_code, -+ (value == gpio->active_level) ? 1 : 0); -+ gpio->old_value = value; -+ } -+ } -+ input_sync(poll_dev->input); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+static void joypad_adc_check(struct input_polled_dev *poll_dev) -+{ -+ struct joypad *joypad = poll_dev->private; -+ int nbtn; -+ int mag; -+ -+ /* Assumes an even number of axes and that joystick axis pairs are sequential */ -+ /* e.g. left stick Y immediately follows left stick X */ -+ for (nbtn = 0; nbtn < joypad->chan_count; nbtn += 2) { -+ struct bt_adc *adcx = &joypad->adcs[nbtn]; -+ struct bt_adc *adcy = &joypad->adcs[nbtn + 1]; -+ -+ /* Read first joystick axis */ -+ adcx->value = joypad_adc_read(joypad, adcx); -+ if (!adcx->value) { -+ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", -+ __func__, nbtn); -+ continue; -+ } -+ adcx->value = adcx->value - adcx->cal; -+ -+ /* Read second joystick axis */ -+ adcy->value = joypad_adc_read(joypad, adcy); -+ if (!adcy->value) { -+ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", -+ __func__, nbtn + 1); -+ continue; -+ } -+ adcy->value = adcy->value - adcy->cal; -+ -+ /* Scaled Radial Deadzone */ -+ /* https://web.archive.org/web/20190129113357/http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html */ -+ mag = int_sqrt((adcx->value * adcx->value) + (adcy->value * adcy->value)); -+ if (joypad->bt_adc_deadzone) { -+ if (mag <= joypad->bt_adc_deadzone) { -+ adcx->value = 0; -+ adcy->value = 0; -+ } -+ else { -+ /* Assumes adcx->max == -adcx->min == adcy->max == -adcy->min */ -+ /* Order of operations is critical to avoid integer overflow */ -+ adcx->value = (((adcx->max * adcx->value) / mag) * (mag - joypad->bt_adc_deadzone)) / (adcx->max - joypad->bt_adc_deadzone); -+ adcy->value = (((adcy->max * adcy->value) / mag) * (mag - joypad->bt_adc_deadzone)) / (adcy->max - joypad->bt_adc_deadzone); -+ } -+ } -+ -+ /* adc data tuning */ -+ if (adcx->tuning_n && adcx->value < 0) -+ adcx->value = ADC_DATA_TUNING(adcx->value, adcx->tuning_n); -+ if (adcx->tuning_p && adcx->value > 0) -+ adcx->value = ADC_DATA_TUNING(adcx->value, adcx->tuning_p); -+ if (adcy->tuning_n && adcy->value < 0) -+ adcy->value = ADC_DATA_TUNING(adcy->value, adcy->tuning_n); -+ if (adcy->tuning_p && adcy->value > 0) -+ adcy->value = ADC_DATA_TUNING(adcy->value, adcy->tuning_p); -+ -+ /* Clamp to [min, max] */ -+ adcx->value = adcx->value > adcx->max ? adcx->max : adcx->value; -+ adcx->value = adcx->value < adcx->min ? adcx->min : adcx->value; -+ adcy->value = adcy->value > adcy->max ? adcy->max : adcy->value; -+ adcy->value = adcy->value < adcy->min ? adcy->min : adcy->value; -+ -+ input_report_abs(poll_dev->input, -+ adcx->report_type, -+ adcx->invert ? adcx->value * (-1) : adcx->value); -+ input_report_abs(poll_dev->input, -+ adcy->report_type, -+ adcy->invert ? adcy->value * (-1) : adcy->value); -+ } -+ input_sync(poll_dev->input); -+} -+ -+/*----------------------------------------------------------------------------*/ -+static void joypad_poll(struct input_polled_dev *poll_dev) -+{ -+ struct joypad *joypad = poll_dev->private; -+ -+ if (joypad->enable) { -+ joypad_adc_check(poll_dev); -+ joypad_gpio_check(poll_dev); -+ } -+ if (poll_dev->poll_interval != joypad->poll_interval) { -+ mutex_lock(&joypad->lock); -+ poll_dev->poll_interval = joypad->poll_interval; -+ mutex_unlock(&joypad->lock); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+static void joypad_open(struct input_polled_dev *poll_dev) -+{ -+ struct joypad *joypad = poll_dev->private; -+ int nbtn; -+ -+ for (nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { -+ struct bt_gpio *gpio = &joypad->gpios[nbtn]; -+ gpio->old_value = gpio->active_level ? 0 : 1; -+ } -+ for (nbtn = 0; nbtn < joypad->chan_count; nbtn++) { -+ struct bt_adc *adc = &joypad->adcs[nbtn]; -+ -+ adc->value = joypad_adc_read(joypad, adc); -+ if (!adc->value) { -+ dev_err(joypad->dev, "%s : saradc channels[%d]!\n", -+ __func__, nbtn); -+ continue; -+ } -+ adc->cal = adc->value; -+ dev_info(joypad->dev, "%s : adc[%d] adc->cal = %d\n", -+ __func__, nbtn, adc->cal); -+ } -+ /* buttons status sync */ -+ joypad_adc_check(poll_dev); -+ joypad_gpio_check(poll_dev); -+ -+ /* button report enable */ -+ mutex_lock(&joypad->lock); -+ joypad->enable = true; -+ mutex_unlock(&joypad->lock); -+ -+ dev_info(joypad->dev, "%s : opened\n", __func__); -+} -+ -+/*----------------------------------------------------------------------------*/ -+static void joypad_close(struct input_polled_dev *poll_dev) -+{ -+ struct joypad *joypad = poll_dev->private; -+ -+ /* button report disable */ -+ mutex_lock(&joypad->lock); -+ joypad->enable = false; -+ mutex_unlock(&joypad->lock); -+ -+ dev_info(joypad->dev, "%s : closed\n", __func__); -+} -+ -+/*----------------------------------------------------------------------------*/ -+static int joypad_iochannel_setup(struct device *dev, struct joypad *joypad) -+{ -+ enum iio_chan_type type; -+ unsigned char cnt; -+ const char *uname; -+ int ret; -+ -+ for (cnt = 0; cnt < joypad->chan_count; cnt++) { -+ -+ ret = of_property_read_string_index(dev->of_node, -+ "io-channel-names", cnt, &uname); -+ if (ret < 0) { -+ dev_err(dev, "invalid channel name index[%d]\n", cnt); -+ return -EINVAL; -+ } -+ -+ joypad->adc_ch[cnt] = devm_iio_channel_get(dev, -+ uname); -+ if (IS_ERR(joypad->adc_ch[cnt])) { -+ dev_err(dev, "iio channel get error\n"); -+ return -EINVAL; -+ } -+ if (!joypad->adc_ch[cnt]->indio_dev) -+ return -ENXIO; -+ -+ if (iio_get_channel_type(joypad->adc_ch[cnt], &type)) -+ return -EINVAL; -+ -+ if (type != IIO_VOLTAGE) { -+ dev_err(dev, "Incompatible channel type %d\n", type); -+ return -EINVAL; -+ } -+ } -+ return ret; -+} -+ -+/*----------------------------------------------------------------------------*/ -+static int joypad_adc_setup(struct device *dev, struct joypad *joypad) -+{ -+ int nbtn; -+ -+ /* adc button struct init */ -+ joypad->adcs = devm_kzalloc(dev, joypad->chan_count * -+ sizeof(struct bt_adc), GFP_KERNEL); -+ if (!joypad->adcs) { -+ dev_err(dev, "%s devm_kzmalloc error!", __func__); -+ return -ENOMEM; -+ } -+ -+ for (nbtn = 0; nbtn < joypad->chan_count; nbtn++) { -+ struct bt_adc *adc = &joypad->adcs[nbtn]; -+ -+ adc->scale = joypad->bt_adc_scale; -+ -+ adc->max = (ADC_MAX_VOLTAGE / 2); -+ adc->min = (ADC_MAX_VOLTAGE / 2) * (-1); -+ if (adc->scale) { -+ adc->max *= adc->scale; -+ adc->min *= adc->scale; -+ } -+ adc->channel = nbtn; -+ adc->invert = false; -+ -+ switch (nbtn) { -+ case 0: -+ adc->report_type = ABS_RY; -+ if (device_property_read_u32(dev, -+ "abs_ry-p-tuning", -+ &adc->tuning_p)) -+ adc->tuning_p = ADC_TUNING_DEFAULT; -+ if (device_property_read_u32(dev, -+ "abs_ry-n-tuning", -+ &adc->tuning_n)) -+ adc->tuning_n = ADC_TUNING_DEFAULT; -+ break; -+ case 1: -+ adc->report_type = ABS_RX; -+ if (device_property_read_u32(dev, -+ "abs_rx-p-tuning", -+ &adc->tuning_p)) -+ adc->tuning_p = ADC_TUNING_DEFAULT; -+ if (device_property_read_u32(dev, -+ "abs_rx-n-tuning", -+ &adc->tuning_n)) -+ adc->tuning_n = ADC_TUNING_DEFAULT; -+ break; -+ case 2: -+ adc->report_type = ABS_Y; -+ if (device_property_read_u32(dev, -+ "abs_y-p-tuning", -+ &adc->tuning_p)) -+ adc->tuning_p = ADC_TUNING_DEFAULT; -+ if (device_property_read_u32(dev, -+ "abs_y-n-tuning", -+ &adc->tuning_n)) -+ adc->tuning_n = ADC_TUNING_DEFAULT; -+ break; -+ case 3: -+ adc->report_type = ABS_X; -+ if (device_property_read_u32(dev, -+ "abs_x-p-tuning", -+ &adc->tuning_p)) -+ adc->tuning_p = ADC_TUNING_DEFAULT; -+ if (device_property_read_u32(dev, -+ "abs_x-n-tuning", -+ &adc->tuning_n)) -+ adc->tuning_n = ADC_TUNING_DEFAULT; -+ break; -+ default : -+ dev_err(dev, "%s io channel count(%d) error!", -+ __func__, nbtn); -+ return -EINVAL; -+ } -+ } -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+static int joypad_gpio_setup(struct device *dev, struct joypad *joypad) -+{ -+ struct device_node *node, *pp; -+ int nbtn; -+ -+ node = dev->of_node; -+ if (!node) -+ return -ENODEV; -+ -+ joypad->gpios = devm_kzalloc(dev, joypad->bt_gpio_count * -+ sizeof(struct bt_gpio), GFP_KERNEL); -+ -+ if (!joypad->gpios) { -+ dev_err(dev, "%s devm_kzmalloc error!", __func__); -+ return -ENOMEM; -+ } -+ -+ nbtn = 0; -+ for_each_child_of_node(node, pp) { -+ enum of_gpio_flags flags; -+ struct bt_gpio *gpio = &joypad->gpios[nbtn++]; -+ int error; -+ -+ gpio->num = of_get_gpio_flags(pp, 0, &flags); -+ if (gpio->num < 0) { -+ error = gpio->num; -+ dev_err(dev, "Failed to get gpio flags, error: %d\n", -+ error); -+ return error; -+ } -+ -+ /* gpio active level(key press level) */ -+ gpio->active_level = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; -+ -+ gpio->label = of_get_property(pp, "label", NULL); -+ -+ if (gpio_is_valid(gpio->num)) { -+ error = devm_gpio_request_one(dev, gpio->num, -+ GPIOF_IN, gpio->label); -+ if (error < 0) { -+ dev_err(dev, -+ "Failed to request GPIO %d, error %d\n", -+ gpio->num, error); -+ return error; -+ } -+ #if 0 -+ error = gpiod_set_pull(gpio_to_desc(gpio->num), GPIOD_PULL_UP); -+ if (error < 0) { -+ dev_err(dev, -+ "Failed to set pull-up GPIO %d, error %d\n", -+ gpio->num, error); -+ return error; -+ } -+ #endif -+ } -+ if (of_property_read_u32(pp, "linux,code", &gpio->linux_code)) { -+ dev_err(dev, "Button without keycode: 0x%x\n", -+ gpio->num); -+ return -EINVAL; -+ } -+ if (of_property_read_u32(pp, "linux,input-type", -+ &gpio->report_type)) -+ gpio->report_type = EV_KEY; -+ } -+ if (nbtn == 0) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+static int joypad_input_setup(struct device *dev, struct joypad *joypad) -+{ -+ struct input_polled_dev *poll_dev; -+ struct input_dev *input; -+ int nbtn, error; -+ u32 joypad_vendor = 0; -+ u32 joypad_revision = 0; -+ u32 joypad_product = 0; -+ -+ poll_dev = devm_input_allocate_polled_device(dev); -+ if (!poll_dev) { -+ dev_err(dev, "no memory for polled device\n"); -+ return -ENOMEM; -+ } -+ -+ poll_dev->private = joypad; -+ poll_dev->poll = joypad_poll; -+ poll_dev->poll_interval = joypad->poll_interval; -+ poll_dev->open = joypad_open; -+ poll_dev->close = joypad_close; -+ -+ input = poll_dev->input; -+ -+ input->name = DRV_NAME; -+ -+ device_property_read_string(dev, "joypad-name", &input->name); -+ input->phys = DRV_NAME"/input0"; -+ -+ device_property_read_u32(dev, "joypad-vendor", &joypad_vendor); -+ device_property_read_u32(dev, "joypad-revision", &joypad_revision); -+ device_property_read_u32(dev, "joypad-product", &joypad_product); -+ //input->id.bustype = BUS_HOST; -+ input->id.bustype = BUS_USB; -+ input->id.vendor = (u16)joypad_vendor; -+ input->id.product = (u16)joypad_product; -+ input->id.version = (u16)joypad_revision; -+ -+ /* IIO ADC key setup (0 mv ~ 1800 mv) * adc->scale */ -+ __set_bit(EV_ABS, input->evbit); -+ -+ // Set mapped ones on dt -+ for(nbtn = 0; nbtn < joypad->chan_count; nbtn++) { -+ struct bt_adc *adc = &joypad->adcs[nbtn]; -+ input_set_abs_params(input, adc->report_type, -+ adc->min, adc->max, -+ joypad->bt_adc_fuzz, -+ joypad->bt_adc_flat); -+ dev_info(dev, -+ "%s : SCALE = %d, ABS min = %d, max = %d," -+ " fuzz = %d, flat = %d, deadzone = %d\n", -+ __func__, adc->scale, adc->min, adc->max, -+ joypad->bt_adc_fuzz, joypad->bt_adc_flat, -+ joypad->bt_adc_deadzone); -+ dev_info(dev, -+ "%s : adc tuning_p = %d, adc_tuning_n = %d\n\n", -+ __func__, adc->tuning_p, adc->tuning_n); -+ } -+ -+ /* GPIO key setup */ -+ __set_bit(EV_KEY, input->evbit); -+ for(nbtn = 0; nbtn < joypad->bt_gpio_count; nbtn++) { -+ struct bt_gpio *gpio = &joypad->gpios[nbtn]; -+ input_set_capability(input, gpio->report_type, -+ gpio->linux_code); -+ } -+ -+ if (joypad->auto_repeat) -+ __set_bit(EV_REP, input->evbit); -+ -+ joypad->dev = dev; -+ -+ error = input_register_polled_device(poll_dev); -+ if (error) { -+ dev_err(dev, "unable to register polled device, err=%d\n", -+ error); -+ return error; -+ } -+ joypad->dev = dev; -+ joypad->poll_dev = poll_dev; -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+static void joypad_setup_value_check(struct device *dev, struct joypad *joypad) -+{ -+ /* -+ fuzz: specifies fuzz value that is used to filter noise from -+ the event stream. -+ */ -+ if (g_button_adc_fuzz) -+ joypad->bt_adc_fuzz = g_button_adc_fuzz; -+ else -+ device_property_read_u32(dev, "button-adc-fuzz", -+ &joypad->bt_adc_fuzz); -+ /* -+ flat: values that are within this value will be discarded by -+ joydev interface and reported as 0 instead. -+ */ -+ if (g_button_adc_flat) -+ joypad->bt_adc_flat = g_button_adc_flat; -+ else -+ device_property_read_u32(dev, "button-adc-flat", -+ &joypad->bt_adc_flat); -+ -+ /* Joystick report value control */ -+ if (g_button_adc_scale) -+ joypad->bt_adc_scale = g_button_adc_scale; -+ else -+ device_property_read_u32(dev, "button-adc-scale", -+ &joypad->bt_adc_scale); -+ -+ /* Joystick deadzone value control */ -+ if (g_button_adc_deadzone) -+ joypad->bt_adc_deadzone = g_button_adc_deadzone; -+ else -+ device_property_read_u32(dev, "button-adc-deadzone", -+ &joypad->bt_adc_deadzone); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+static int joypad_dt_parse(struct device *dev, struct joypad *joypad) -+{ -+ int error = 0; -+ -+ /* initialize value check from boot.ini */ -+ joypad_setup_value_check(dev, joypad); -+ -+ joypad->chan_count = of_property_count_strings(dev->of_node, -+ "io-channel-names"); -+ -+ device_property_read_u32(dev, "poll-interval", -+ &joypad->poll_interval); -+ -+ joypad->auto_repeat = device_property_present(dev, "autorepeat"); -+ -+ joypad->bt_gpio_count = device_get_child_node_count(dev); -+ -+ if ((joypad->chan_count == 0) || (joypad->bt_gpio_count == 0)) { -+ dev_err(dev, "adc key = %d, gpio key = %d error!", -+ joypad->chan_count, joypad->bt_gpio_count); -+ return -EINVAL; -+ } -+ -+ error = joypad_adc_setup(dev, joypad); -+ if (error) -+ return error; -+ -+ error = joypad_iochannel_setup(dev, joypad); -+ if (error) -+ return error; -+ -+ error = joypad_gpio_setup(dev, joypad); -+ if (error) -+ return error; -+ -+ dev_info(dev, "%s : adc key cnt = %d, gpio key cnt = %d\n", -+ __func__, joypad->chan_count, joypad->bt_gpio_count); -+ -+ return error; -+} -+ -+/*----------------------------------------------------------------------------*/ -+static int joypad_probe(struct platform_device *pdev) -+{ -+ struct joypad *joypad; -+ struct device *dev = &pdev->dev; -+ int error; -+ -+ joypad = devm_kzalloc(dev, sizeof(struct joypad), GFP_KERNEL); -+ if (!joypad) { -+ dev_err(dev, "joypad devm_kzmalloc error!"); -+ return -ENOMEM; -+ } -+ -+ /* device tree data parse */ -+ error = joypad_dt_parse(dev, joypad); -+ if (error) { -+ dev_err(dev, "dt parse error!(err = %d)\n", error); -+ return error; -+ } -+ -+ mutex_init(&joypad->lock); -+ platform_set_drvdata(pdev, joypad); -+ -+ error = sysfs_create_group(&pdev->dev.kobj, &joypad_attr_group); -+ if (error) { -+ dev_err(dev, "create sysfs group fail, error: %d\n", -+ error); -+ return error; -+ } -+ -+ /* poll input device setup */ -+ error = joypad_input_setup(dev, joypad); -+ if (error) { -+ dev_err(dev, "input setup failed!(err = %d)\n", error); -+ return error; -+ } -+ dev_info(dev, "%s : probe success\n", __func__); -+ return 0; -+} -+ -+static void joypad_shutdown(struct platform_device *pdev) -+{ -+ struct joypad *joypad = platform_get_drvdata(pdev); -+ input_unregister_polled_device(joypad->poll_dev); -+} -+/*----------------------------------------------------------------------------*/ -+static const struct of_device_id joypad_of_match[] = { -+ { .compatible = "odroidgou-joypad", }, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(of, joypad_of_match); -+ -+/*----------------------------------------------------------------------------*/ -+static struct platform_driver joypad_driver = { -+ .probe = joypad_probe, -+ .shutdown = joypad_shutdown, -+ .driver = { -+ .name = DRV_NAME, -+ .of_match_table = of_match_ptr(joypad_of_match), -+ }, -+}; -+ -+/*----------------------------------------------------------------------------*/ -+static int __init joypad_init(void) -+{ -+ return platform_driver_register(&joypad_driver); -+} -+ -+/*----------------------------------------------------------------------------*/ -+static void __exit joypad_exit(void) -+{ -+ platform_driver_unregister(&joypad_driver); -+} -+ -+/*----------------------------------------------------------------------------*/ -+late_initcall(joypad_init); -+module_exit(joypad_exit); -+ -+/*----------------------------------------------------------------------------*/ -+MODULE_AUTHOR("Hardkernel Co.,LTD"); -+MODULE_DESCRIPTION("Keypad driver(ADC&GPIO) for ODROIDGO-Advance"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" DRV_NAME); -+ -+/*----------------------------------------------------------------------------*/ -diff -rupN linux.orig/drivers/mfd/rk808.c linux/drivers/mfd/rk808.c ---- linux.orig/drivers/mfd/rk808.c 2023-09-12 12:02:58.341633584 +0000 -+++ linux/drivers/mfd/rk808.c 2023-09-12 12:03:27.490291628 +0000 -@@ -81,12 +81,47 @@ static bool rk817_is_volatile_reg(struct - return false; - } - -+static bool rk818_is_volatile_reg(struct device *dev, unsigned int reg) -+{ -+ /* -+ * Notes: -+ * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but -+ * we don't use that feature. It's better to cache. -+ * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since -+ * bits are cleared in case when we shutoff anyway, but better safe. -+ */ -+ -+ switch (reg) { -+ case RK808_SECONDS_REG ... RK808_WEEKS_REG: -+ case RK808_RTC_STATUS_REG: -+ case RK808_VB_MON_REG: -+ case RK808_THERMAL_REG: -+ case RK808_DCDC_EN_REG: -+ case RK808_LDO_EN_REG: -+ case RK808_DCDC_UV_STS_REG: -+ case RK808_LDO_UV_STS_REG: -+ case RK808_DCDC_PG_REG: -+ case RK808_LDO_PG_REG: -+ case RK808_DEVCTRL_REG: -+ case RK808_INT_STS_REG1: -+ case RK808_INT_STS_REG2: -+ case RK808_INT_STS_MSK_REG1: -+ case RK808_INT_STS_MSK_REG2: -+ case RK818_LDO8_ON_VSEL_REG: // TODO(ayufan):?? -+ case RK818_LDO8_SLP_VSEL_REG: // TODO(ayufan):?? -+ case RK818_SUP_STS_REG ... RK818_SAVE_DATA19: -+ return true; -+ } -+ -+ return false; -+} -+ - static const struct regmap_config rk818_regmap_config = { - .reg_bits = 8, - .val_bits = 8, -- .max_register = RK818_USB_CTRL_REG, -+ .max_register = RK818_SAVE_DATA19, - .cache_type = REGCACHE_RBTREE, -- .volatile_reg = rk808_is_volatile_reg, -+ .volatile_reg = rk818_is_volatile_reg, - }; - - static const struct regmap_config rk805_regmap_config = { -@@ -137,58 +172,67 @@ static const struct resource rk817_charg - }; - - static const struct mfd_cell rk805s[] = { -- { .name = "rk808-clkout", }, -- { .name = "rk808-regulator", }, -- { .name = "rk805-pinctrl", }, -+ { .name = "rk808-clkout", .id = -1, }, -+ { .name = "rk808-regulator", .id = -1, }, -+ { .name = "rk805-pinctrl", .id = -1, }, - { - .name = "rk808-rtc", - .num_resources = ARRAY_SIZE(rtc_resources), - .resources = &rtc_resources[0], -+ .id = -1, - }, - { .name = "rk805-pwrkey", - .num_resources = ARRAY_SIZE(rk805_key_resources), - .resources = &rk805_key_resources[0], -+ .id = -1, - }, - }; - - static const struct mfd_cell rk808s[] = { -- { .name = "rk808-clkout", }, -- { .name = "rk808-regulator", }, -+ { .name = "rk808-clkout", .id = -1, }, -+ { .name = "rk808-regulator", .id = -1, }, - { - .name = "rk808-rtc", - .num_resources = ARRAY_SIZE(rtc_resources), - .resources = rtc_resources, -+ .id = -1, - }, - }; - - static const struct mfd_cell rk817s[] = { -- { .name = "rk808-clkout",}, -- { .name = "rk808-regulator",}, -+ { .name = "rk808-clkout", .id = -1, }, -+ { .name = "rk808-regulator", .id = -1, }, - { - .name = "rk805-pwrkey", - .num_resources = ARRAY_SIZE(rk817_pwrkey_resources), - .resources = &rk817_pwrkey_resources[0], -+ .id = -1, - }, - { - .name = "rk808-rtc", - .num_resources = ARRAY_SIZE(rk817_rtc_resources), - .resources = &rk817_rtc_resources[0], -+ .id = -1, - }, -- { .name = "rk817-codec",}, -+ { .name = "rk817-codec", .id = -1, }, - { - .name = "rk817-charger", - .num_resources = ARRAY_SIZE(rk817_charger_resources), - .resources = &rk817_charger_resources[0], -+ .id = -1, - }, - }; - - static const struct mfd_cell rk818s[] = { -- { .name = "rk808-clkout", }, -- { .name = "rk808-regulator", }, -+ { .name = "rk808-clkout", .id = -1, }, -+ { .name = "rk808-regulator", .id = -1, }, -+ { .name = "rk818-battery", .of_compatible = "rockchip,rk818-battery", }, -+ { .name = "rk818-charger", .of_compatible = "rockchip,rk818-charger", }, - { - .name = "rk808-rtc", - .num_resources = ARRAY_SIZE(rtc_resources), - .resources = rtc_resources, -+ .id = -1, - }, - }; - -@@ -318,6 +362,7 @@ static const struct rk808_reg_data rk818 - { RK818_H5V_EN_REG, BIT(0), RK818_H5V_EN }, - { RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT | - VB_LO_SEL_3500MV }, -+ { RK808_CLK32OUT_REG, CLK32KOUT2_FUNC_MASK, CLK32KOUT2_FUNC }, - }; - - static const struct regmap_irq rk805_irqs[] = { -diff -rupN linux.orig/drivers/power/reset/Kconfig linux/drivers/power/reset/Kconfig ---- linux.orig/drivers/power/reset/Kconfig 2023-09-12 12:02:58.741642619 +0000 -+++ linux/drivers/power/reset/Kconfig 2023-09-12 12:03:27.490291628 +0000 -@@ -141,6 +141,13 @@ config POWER_RESET_OCELOT_RESET - help - This driver supports restart for Microsemi Ocelot SoC and similar. - -+config POWER_RESET_ODROID_GO_ULTRA_POWEROFF -+ bool "Odroid Go Ultra power-off driver" -+ depends on ARCH_MESON || COMPILE_TEST -+ depends on I2C=y && OF -+ help -+ This driver supports Power off for Odroid Go Ultra device. -+ - config POWER_RESET_OXNAS - bool "OXNAS SoC restart driver" - depends on ARCH_OXNAS -diff -rupN linux.orig/drivers/power/reset/Makefile linux/drivers/power/reset/Makefile ---- linux.orig/drivers/power/reset/Makefile 2023-09-12 12:02:58.741642619 +0000 -+++ linux/drivers/power/reset/Makefile 2023-09-12 12:03:27.490291628 +0000 -@@ -17,6 +17,7 @@ obj-$(CONFIG_POWER_RESET_MT6323) += mt63 - obj-$(CONFIG_POWER_RESET_OXNAS) += oxnas-restart.o - obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o - obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o -+obj-$(CONFIG_POWER_RESET_ODROID_GO_ULTRA_POWEROFF) += odroid-go-ultra-poweroff.o - obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o - obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o - obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o -diff -rupN linux.orig/drivers/power/reset/odroid-go-ultra-poweroff.c linux/drivers/power/reset/odroid-go-ultra-poweroff.c ---- linux.orig/drivers/power/reset/odroid-go-ultra-poweroff.c 1970-01-01 00:00:00.000000000 +0000 -+++ linux/drivers/power/reset/odroid-go-ultra-poweroff.c 2023-09-12 12:03:27.490291628 +0000 -@@ -0,0 +1,177 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (c) 2023 Neil Armstrong -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * The Odroid Go Ultra has 2 PMICs: -+ * - RK818 (manages the battery and USB-C power supply) -+ * - RK817 -+ * Both PMICs feeds power to the S922X SoC, so they must be powered-off in sequence. -+ * Vendor does power-off the RK817 first, then the RK818 so here we follow this sequence. -+ */ -+ -+struct odroid_go_ultra_poweroff_data { -+ struct device *dev; -+ struct device *rk817; -+ struct device *rk818; -+}; -+ -+static int odroid_go_ultra_poweroff_prepare(struct sys_off_data *data) -+{ -+ struct odroid_go_ultra_poweroff_data *poweroff_data = data->cb_data; -+ struct regmap *rk817, *rk818; -+ int ret; -+ -+ /* RK817 Regmap */ -+ rk817 = dev_get_regmap(poweroff_data->rk817, NULL); -+ if (!rk817) { -+ dev_err(poweroff_data->dev, "failed to get rk817 regmap\n"); -+ return notifier_from_errno(-EINVAL); -+ } -+ -+ /* RK818 Regmap */ -+ rk818 = dev_get_regmap(poweroff_data->rk818, NULL); -+ if (!rk818) { -+ dev_err(poweroff_data->dev, "failed to get rk818 regmap\n"); -+ return notifier_from_errno(-EINVAL); -+ } -+ -+ dev_info(poweroff_data->dev, "Setting PMICs for power off"); -+ -+ /* RK817 */ -+ ret = regmap_update_bits(rk817, RK817_SYS_CFG(3), DEV_OFF, DEV_OFF); -+ if (ret) { -+ dev_err(poweroff_data->dev, "failed to poweroff rk817\n"); -+ return notifier_from_errno(ret); -+ } -+ -+ /* RK818 */ -+ ret = regmap_update_bits(rk818, RK818_DEVCTRL_REG, DEV_OFF, DEV_OFF); -+ if (ret) { -+ dev_err(poweroff_data->dev, "failed to poweroff rk818\n"); -+ return notifier_from_errno(ret); -+ } -+ -+ return NOTIFY_OK; -+} -+ -+static void odroid_go_ultra_poweroff_put_pmic_device(void *data) -+{ -+ struct device *dev = data; -+ -+ put_device(dev); -+} -+ -+static int odroid_go_ultra_poweroff_get_pmic_device(struct device *dev, const char *compatible, -+ struct device **pmic) -+{ -+ struct device_node *pmic_node; -+ struct i2c_client *pmic_client; -+ -+ pmic_node = of_find_compatible_node(NULL, NULL, compatible); -+ if (!pmic_node) -+ return -ENODEV; -+ -+ pmic_client = of_find_i2c_device_by_node(pmic_node); -+ of_node_put(pmic_node); -+ if (!pmic_client) -+ return -EPROBE_DEFER; -+ -+ *pmic = &pmic_client->dev; -+ -+ return devm_add_action_or_reset(dev, odroid_go_ultra_poweroff_put_pmic_device, *pmic); -+} -+ -+static int odroid_go_ultra_poweroff_probe(struct platform_device *pdev) -+{ -+ struct odroid_go_ultra_poweroff_data *poweroff_data; -+ int ret; -+ -+ poweroff_data = devm_kzalloc(&pdev->dev, sizeof(*poweroff_data), GFP_KERNEL); -+ if (!poweroff_data) -+ return -ENOMEM; -+ -+ dev_set_drvdata(&pdev->dev, poweroff_data); -+ -+ /* RK818 PMIC Device */ -+ ret = odroid_go_ultra_poweroff_get_pmic_device(&pdev->dev, "rockchip,rk818", -+ &poweroff_data->rk818); -+ if (ret) -+ return dev_err_probe(&pdev->dev, ret, "failed to get rk818 mfd data\n"); -+ -+ /* RK817 PMIC Device */ -+ ret = odroid_go_ultra_poweroff_get_pmic_device(&pdev->dev, "rockchip,rk817", -+ &poweroff_data->rk817); -+ if (ret) -+ return dev_err_probe(&pdev->dev, ret, "failed to get rk817 mfd data\n"); -+ -+ /* Register as SYS_OFF_MODE_POWER_OFF_PREPARE because regmap_update_bits may sleep */ -+ ret = devm_register_sys_off_handler(&pdev->dev, -+ SYS_OFF_MODE_POWER_OFF_PREPARE, -+ SYS_OFF_PRIO_DEFAULT, -+ odroid_go_ultra_poweroff_prepare, -+ poweroff_data); -+ if (ret) -+ return dev_err_probe(&pdev->dev, ret, "failed to register sys-off handler\n"); -+ -+ dev_info(&pdev->dev, "Registered Power-Off handler\n"); -+ -+ return 0; -+} -+static struct platform_device *pdev; -+ -+static struct platform_driver odroid_go_ultra_poweroff_driver = { -+ .driver = { -+ .name = "odroid-go-ultra-poweroff", -+ }, -+ .probe = odroid_go_ultra_poweroff_probe, -+}; -+ -+static int __init odroid_go_ultra_poweroff_init(void) -+{ -+ int ret; -+ -+ /* Only create when running on the Odroid Go Ultra device */ -+ if (!of_device_is_compatible(of_root, "hardkernel,odroid-go-ultra")) -+ return -ENODEV; -+ -+ ret = platform_driver_register(&odroid_go_ultra_poweroff_driver); -+ if (ret) -+ return ret; -+ -+ pdev = platform_device_register_resndata(NULL, "odroid-go-ultra-poweroff", -1, -+ NULL, 0, NULL, 0); -+ -+ if (IS_ERR(pdev)) { -+ platform_driver_unregister(&odroid_go_ultra_poweroff_driver); -+ return PTR_ERR(pdev); -+ } -+ -+ return 0; -+} -+ -+static void __exit odroid_go_ultra_poweroff_exit(void) -+{ -+ /* Only delete when running on the Odroid Go Ultra device */ -+ if (!of_device_is_compatible(of_root, "hardkernel,odroid-go-ultra")) -+ return; -+ -+ platform_device_unregister(pdev); -+ platform_driver_unregister(&odroid_go_ultra_poweroff_driver); -+} -+ -+module_init(odroid_go_ultra_poweroff_init); -+module_exit(odroid_go_ultra_poweroff_exit); -+ -+MODULE_AUTHOR("Neil Armstrong "); -+MODULE_DESCRIPTION("Odroid Go Ultra poweroff driver"); -+MODULE_LICENSE("GPL"); diff -rupN linux.orig/drivers/power/supply/Kconfig linux/drivers/power/supply/Kconfig --- linux.orig/drivers/power/supply/Kconfig 2023-09-12 12:02:58.745642709 +0000 +++ linux/drivers/power/supply/Kconfig 2023-09-12 12:03:27.490291628 +0000 @@ -8564,31 +4601,142 @@ diff -rupN linux.orig/include/linux/mfd/rk808.h linux/include/linux/mfd/rk808.h #define TEMP115C 0x0c #define TEMP_HOTDIE_MSK 0x0c -diff -rupN linux.orig/sound/soc/meson/axg-card.c linux/sound/soc/meson/axg-card.c ---- linux.orig/sound/soc/meson/axg-card.c 2023-09-12 12:02:59.597661952 +0000 -+++ linux/sound/soc/meson/axg-card.c 2023-09-12 12:03:27.490291628 +0000 -@@ -59,6 +59,13 @@ static int axg_card_tdm_dai_init(struct - (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num]; - struct snd_soc_dai *codec_dai; - int ret, i; -+ struct snd_soc_card *card = rtd->card; +diff -rupN linux.orig/drivers/mfd/rk808.c linux/drivers/mfd/rk808.c +--- linux.orig/drivers/mfd/rk808.c 2023-09-12 12:02:58.341633584 +0000 ++++ linux/drivers/mfd/rk808.c 2023-09-12 12:03:27.490291628 +0000 +@@ -81,12 +81,47 @@ static bool rk817_is_volatile_reg(struct + return false; + } + ++static bool rk818_is_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ /* ++ * Notes: ++ * - Technically the ROUND_30s bit makes RTC_CTRL_REG volatile, but ++ * we don't use that feature. It's better to cache. ++ * - It's unlikely we care that RK808_DEVCTRL_REG is volatile since ++ * bits are cleared in case when we shutoff anyway, but better safe. ++ */ + -+ /* Go-Ultra : Digital volume is limited to -2dB */ -+ ret = snd_soc_limit_volume(card, "Master Playback Volume", 252); -+ if (ret < 0) -+ dev_dbg(codec_dai->dev, -+ "Not found mixer : 'Master Playback Volume'\n"); ++ switch (reg) { ++ case RK808_SECONDS_REG ... RK808_WEEKS_REG: ++ case RK808_RTC_STATUS_REG: ++ case RK808_VB_MON_REG: ++ case RK808_THERMAL_REG: ++ case RK808_DCDC_EN_REG: ++ case RK808_LDO_EN_REG: ++ case RK808_DCDC_UV_STS_REG: ++ case RK808_LDO_UV_STS_REG: ++ case RK808_DCDC_PG_REG: ++ case RK808_LDO_PG_REG: ++ case RK808_DEVCTRL_REG: ++ case RK808_INT_STS_REG1: ++ case RK808_INT_STS_REG2: ++ case RK808_INT_STS_MSK_REG1: ++ case RK808_INT_STS_MSK_REG2: ++ case RK818_LDO8_ON_VSEL_REG: // TODO(ayufan):?? ++ case RK818_LDO8_SLP_VSEL_REG: // TODO(ayufan):?? ++ case RK818_SUP_STS_REG ... RK818_SAVE_DATA19: ++ return true; ++ } ++ ++ return false; ++} ++ + static const struct regmap_config rk818_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +- .max_register = RK818_USB_CTRL_REG, ++ .max_register = RK818_SAVE_DATA19, + .cache_type = REGCACHE_RBTREE, +- .volatile_reg = rk808_is_volatile_reg, ++ .volatile_reg = rk818_is_volatile_reg, + }; - for_each_rtd_codec_dais(rtd, i, codec_dai) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, ---- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi -+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi -@@ -45,7 +45,7 @@ - led-blue { - label = "n2:blue"; - gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; -- linux,default-trigger = "heartbeat"; -+ linux,default-trigger = "none"; - }; - }; + static const struct regmap_config rk805_regmap_config = { +@@ -137,58 +172,67 @@ static const struct resource rk817_charg + }; + static const struct mfd_cell rk805s[] = { +- { .name = "rk808-clkout", }, +- { .name = "rk808-regulator", }, +- { .name = "rk805-pinctrl", }, ++ { .name = "rk808-clkout", .id = -1, }, ++ { .name = "rk808-regulator", .id = -1, }, ++ { .name = "rk805-pinctrl", .id = -1, }, + { + .name = "rk808-rtc", + .num_resources = ARRAY_SIZE(rtc_resources), + .resources = &rtc_resources[0], ++ .id = -1, + }, + { .name = "rk805-pwrkey", + .num_resources = ARRAY_SIZE(rk805_key_resources), + .resources = &rk805_key_resources[0], ++ .id = -1, + }, + }; + + static const struct mfd_cell rk808s[] = { +- { .name = "rk808-clkout", }, +- { .name = "rk808-regulator", }, ++ { .name = "rk808-clkout", .id = -1, }, ++ { .name = "rk808-regulator", .id = -1, }, + { + .name = "rk808-rtc", + .num_resources = ARRAY_SIZE(rtc_resources), + .resources = rtc_resources, ++ .id = -1, + }, + }; + + static const struct mfd_cell rk817s[] = { +- { .name = "rk808-clkout",}, +- { .name = "rk808-regulator",}, ++ { .name = "rk808-clkout", .id = -1, }, ++ { .name = "rk808-regulator", .id = -1, }, + { + .name = "rk805-pwrkey", + .num_resources = ARRAY_SIZE(rk817_pwrkey_resources), + .resources = &rk817_pwrkey_resources[0], ++ .id = -1, + }, + { + .name = "rk808-rtc", + .num_resources = ARRAY_SIZE(rk817_rtc_resources), + .resources = &rk817_rtc_resources[0], ++ .id = -1, + }, +- { .name = "rk817-codec",}, ++ { .name = "rk817-codec", .id = -1, }, + { + .name = "rk817-charger", + .num_resources = ARRAY_SIZE(rk817_charger_resources), + .resources = &rk817_charger_resources[0], ++ .id = -1, + }, + }; + + static const struct mfd_cell rk818s[] = { +- { .name = "rk808-clkout", }, +- { .name = "rk808-regulator", }, ++ { .name = "rk808-clkout", .id = -1, }, ++ { .name = "rk808-regulator", .id = -1, }, ++ { .name = "rk818-battery", .of_compatible = "rockchip,rk818-battery", }, ++ { .name = "rk818-charger", .of_compatible = "rockchip,rk818-charger", }, + { + .name = "rk808-rtc", + .num_resources = ARRAY_SIZE(rtc_resources), + .resources = rtc_resources, ++ .id = -1, + }, + }; + +@@ -318,6 +362,7 @@ static const struct rk808_reg_data rk818 + { RK818_H5V_EN_REG, BIT(0), RK818_H5V_EN }, + { RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT | + VB_LO_SEL_3500MV }, ++ { RK808_CLK32OUT_REG, CLK32KOUT2_FUNC_MASK, CLK32KOUT2_FUNC }, + }; + + static const struct regmap_irq rk805_irqs[] = { diff --git a/projects/Amlogic/packages/linux/patches/S922X/003-dsi-driver.patch b/projects/Amlogic/packages/linux/patches/S922X/004.05-dsi-driver.patch similarity index 99% rename from projects/Amlogic/packages/linux/patches/S922X/003-dsi-driver.patch rename to projects/Amlogic/packages/linux/patches/S922X/004.05-dsi-driver.patch index c98c84d63..ec86a1ada 100644 --- a/projects/Amlogic/packages/linux/patches/S922X/003-dsi-driver.patch +++ b/projects/Amlogic/packages/linux/patches/S922X/004.05-dsi-driver.patch @@ -1,7 +1,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi --- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi 2023-08-22 23:19:15.430576261 +0000 +++ linux/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi 2023-08-22 23:08:18.677044634 +0000 -@@ -1644,9 +1644,28 @@ +@@ -1656,9 +1656,28 @@ <250000000>, <0>; /* Do Nothing */ }; @@ -30,7 +30,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi linux/ar usb3_pcie_phy: phy@46000 { compatible = "amlogic,g12a-usb3-pcie-phy"; reg = <0x0 0x46000 0x0 0x2000>; -@@ -2140,6 +2159,15 @@ +@@ -2143,6 +2162,15 @@ remote-endpoint = <&hdmi_tx_in>; }; }; @@ -46,7 +46,7 @@ diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi linux/ar }; gic: interrupt-controller@ffc01000 { -@@ -2177,6 +2205,48 @@ +@@ -2180,6 +2208,48 @@ amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>; }; diff --git a/projects/Amlogic/packages/linux/patches/S922X/004.06-digital-volume-is-limited-to.patch b/projects/Amlogic/packages/linux/patches/S922X/004.06-digital-volume-is-limited-to.patch new file mode 100644 index 000000000..899a06e86 --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/004.06-digital-volume-is-limited-to.patch @@ -0,0 +1,17 @@ +diff -rupN linux.orig/sound/soc/meson/axg-card.c linux/sound/soc/meson/axg-card.c +--- linux.orig/sound/soc/meson/axg-card.c 2023-09-12 12:02:59.597661952 +0000 ++++ linux/sound/soc/meson/axg-card.c 2023-09-12 12:03:27.490291628 +0000 +@@ -59,6 +59,13 @@ static int axg_card_tdm_dai_init(struct + (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num]; + struct snd_soc_dai *codec_dai; + int ret, i; ++ struct snd_soc_card *card = rtd->card; ++ ++ /* Go-Ultra : Digital volume is limited to -2dB */ ++ ret = snd_soc_limit_volume(card, "Master Playback Volume", 252); ++ if (ret < 0) ++ dev_dbg(codec_dai->dev, ++ "Not found mixer : 'Master Playback Volume'\n"); + + for_each_rtd_codec_dais(rtd, i, codec_dai) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, diff --git a/projects/Amlogic/packages/linux/patches/S922X/005.01-add-uart-ao-b-pins-to-device-trees.patch b/projects/Amlogic/packages/linux/patches/S922X/005.01-add-uart-ao-b-pins-to-device-trees.patch new file mode 100644 index 000000000..b0a389bb1 --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/005.01-add-uart-ao-b-pins-to-device-trees.patch @@ -0,0 +1,19 @@ +diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +--- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi 2023-09-12 12:02:56.937601871 +0000 ++++ linux/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi 2023-09-12 12:03:27.490291628 +0000 +@@ -1903,6 +1891,15 @@ + }; + }; + ++ uart_ao_b_pins: uart-b-ao { ++ mux { ++ groups = "uart_ao_b_tx_8", ++ "uart_ao_b_rx_9"; ++ function = "uart_ao_b"; ++ bias-disable; ++ }; ++ }; ++ + uart_ao_a_pins: uart-a-ao { + mux { + groups = "uart_ao_a_tx", diff --git a/projects/Amlogic/packages/linux/patches/S922X/005.02-gpu-cpu-opp-table-updates.patch b/projects/Amlogic/packages/linux/patches/S922X/005.02-gpu-cpu-opp-table-updates.patch new file mode 100644 index 000000000..fa2a6ff5d --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/005.02-gpu-cpu-opp-table-updates.patch @@ -0,0 +1,76 @@ +diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +--- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi 2023-09-12 12:02:56.937601871 +0000 ++++ linux/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi 2023-09-12 12:03:27.490291628 +0000 +@@ -61,18 +61,6 @@ + gpu_opp_table: opp-table-gpu { + compatible = "operating-points-v2"; + +- opp-124999998 { +- opp-hz = /bits/ 64 <124999998>; +- opp-microvolt = <800000>; +- }; +- opp-249999996 { +- opp-hz = /bits/ 64 <249999996>; +- opp-microvolt = <800000>; +- }; +- opp-285714281 { +- opp-hz = /bits/ 64 <285714281>; +- opp-microvolt = <800000>; +- }; + opp-399999994 { + opp-hz = /bits/ 64 <399999994>; + opp-microvolt = <800000>; +diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi +--- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi 2023-09-12 12:02:56.937601871 +0000 ++++ linux/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi 2023-09-12 12:03:27.490291628 +0000 +@@ -11,6 +11,11 @@ + compatible = "operating-points-v2"; + opp-shared; + ++ opp-667000000 { ++ opp-hz = /bits/ 64 <667000000>; ++ opp-microvolt = <731000>; ++ }; ++ + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <761000>; +@@ -51,6 +56,11 @@ + compatible = "operating-points-v2"; + opp-shared; + ++ opp-667000000 { ++ opp-hz = /bits/ 64 <667000000>; ++ opp-microvolt = <731000>; ++ }; ++ + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <731000>; +diff -rupN linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi linux/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi +--- linux.orig/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi 2023-09-12 12:02:56.937601871 +0000 ++++ linux/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi 2023-09-12 12:03:27.490291628 +0000 +@@ -11,6 +11,11 @@ + compatible = "operating-points-v2"; + opp-shared; + ++ opp-667000000 { ++ opp-hz = /bits/ 64 <667000000>; ++ opp-microvolt = <731000>; ++ }; ++ + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <731000>; +@@ -56,6 +61,11 @@ + compatible = "operating-points-v2"; + opp-shared; + ++ opp-667000000 { ++ opp-hz = /bits/ 64 <667000000>; ++ opp-microvolt = <751000>; ++ }; ++ + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <771000>; diff --git a/projects/Amlogic/packages/linux/patches/S922X/999.01-arm64-dts-Update-cache-properties-for-amlogic.patch b/projects/Amlogic/packages/linux/patches/S922X/999.01-arm64-dts-Update-cache-properties-for-amlogic.patch new file mode 100644 index 000000000..665ba4cf1 --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/999.01-arm64-dts-Update-cache-properties-for-amlogic.patch @@ -0,0 +1,99 @@ +From 49f65e2eaaf96de1282bb82039386c2d2d04ee53 Mon Sep 17 00:00:00 2001 +From: Pierre Gondois +Date: Mon, 7 Nov 2022 16:56:56 +0100 +Subject: [PATCH] arm64: dts: Update cache properties for amlogic + +The DeviceTree Specification v0.3 specifies that the cache node +'compatible' and 'cache-level' properties are 'required'. Cf. +s3.8 Multi-level and Shared Cache Nodes +The 'cache-unified' property should be present if one of the +properties for unified cache is present ('cache-size', ...). + +Update the Device Trees accordingly. + +Signed-off-by: Pierre Gondois +Reviewed-by: Martin Blumenstingl +Link: https://lore.kernel.org/r/20221107155825.1644604-4-pierre.gondois@arm.com +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-g12a.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-g12b.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 1 + + 6 files changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi +index b4000cf65a9a0a..d2f7cb4e5375f0 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi +@@ -36,6 +36,7 @@ + + l2: l2-cache0 { + compatible = "cache"; ++ cache-level = <2>; + }; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +index 04f797b5a012c8..1648e67afbb6bc 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +@@ -105,6 +105,7 @@ + + l2: l2-cache0 { + compatible = "cache"; ++ cache-level = <2>; + }; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi +index fb0ab27d1f642d..af23d7968181d0 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi +@@ -50,6 +50,7 @@ + + l2: l2-cache0 { + compatible = "cache"; ++ cache-level = <2>; + }; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi +index ee8fcae9f9f00a..9978e619acccda 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi +@@ -105,6 +105,7 @@ + + l2: l2-cache0 { + compatible = "cache"; ++ cache-level = <2>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 023a520054947e..e3c12e0be99d74 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -132,6 +132,7 @@ + + l2: l2-cache0 { + compatible = "cache"; ++ cache-level = <2>; + }; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi +index 80737731af3fe2..d845eb19d93dce 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi +@@ -88,6 +88,7 @@ + + l2: l2-cache0 { + compatible = "cache"; ++ cache-level = <2>; + }; + }; + + diff --git a/projects/Amlogic/packages/linux/patches/S922X/999.02-arm64-dts-amlogic-add-missing-cache-properties.patch b/projects/Amlogic/packages/linux/patches/S922X/999.02-arm64-dts-amlogic-add-missing-cache-properties.patch new file mode 100644 index 000000000..9752e653a --- /dev/null +++ b/projects/Amlogic/packages/linux/patches/S922X/999.02-arm64-dts-amlogic-add-missing-cache-properties.patch @@ -0,0 +1,95 @@ +From c2258a94fae556797085b58c0b6839c41826bd3d Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Sat, 22 Apr 2023 00:32:10 +0200 +Subject: [PATCH] arm64: dts: amlogic: add missing cache properties + +As all level 2 and level 3 caches are unified, add required +cache-unified properties to fix warnings like: + + meson-a1-ad401.dtb: l2-cache0: 'cache-unified' is a required property + +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Martin Blumenstingl +Link: https://lore.kernel.org/r/20230421223211.115612-1-krzysztof.kozlowski@linaro.org +Signed-off-by: Neil Armstrong +--- + arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-g12a.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-g12b.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 1 + + arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 1 + + 6 files changed, 6 insertions(+) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi +index eed96f26284415..c8f344596285ec 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi +@@ -37,6 +37,7 @@ + l2: l2-cache0 { + compatible = "cache"; + cache-level = <2>; ++ cache-unified; + }; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +index b984950591e2f6..768d0ed78dbe63 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +@@ -106,6 +106,7 @@ + l2: l2-cache0 { + compatible = "cache"; + cache-level = <2>; ++ cache-unified; + }; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi +index f58fd2a6fe61cb..543e70669df54a 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi +@@ -51,6 +51,7 @@ + l2: l2-cache0 { + compatible = "cache"; + cache-level = <2>; ++ cache-unified; + }; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi +index 431572b384db92..86e6ceb31d5e26 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi +@@ -106,6 +106,7 @@ + l2: l2-cache0 { + compatible = "cache"; + cache-level = <2>; ++ cache-unified; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +index 11f89bfecb56a8..2673f0dbafe764 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +@@ -133,6 +133,7 @@ + l2: l2-cache0 { + compatible = "cache"; + cache-level = <2>; ++ cache-unified; + }; + }; + +diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi +index 617d322af0df8d..643f94d9d08e10 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi +@@ -89,6 +89,7 @@ + l2: l2-cache0 { + compatible = "cache"; + cache-level = <2>; ++ cache-unified; + }; + }; + diff --git a/projects/Amlogic/packages/linux/patches/S922X/002-controls.patch b/projects/Amlogic/packages/linux/patches/S922X/999.03-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch similarity index 97% rename from projects/Amlogic/packages/linux/patches/S922X/002-controls.patch rename to projects/Amlogic/packages/linux/patches/S922X/999.03-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch index e7c42bd0e..421011b84 100644 --- a/projects/Amlogic/packages/linux/patches/S922X/002-controls.patch +++ b/projects/Amlogic/packages/linux/patches/S922X/999.03-LOCAL-ALSA-Assign-internal-PCM-chmap-ELD-IEC958-kctl.patch @@ -28,7 +28,7 @@ diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 8b6aeb8a78f7d3..eee05d447dece7 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c -@@ -2514,7 +2514,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, +@@ -2516,7 +2516,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, knew.name = "Playback Channel Map"; else knew.name = "Capture Channel Map";