diff --git a/app-mobilephone/pinephone-meta/files/00-journal-size.conf b/app-mobilephone/pinephone-meta/files/00-journal-size.conf
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/01-phoc-scaling b/app-mobilephone/pinephone-meta/files/01-phoc-scaling
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/10-pinephone-brightness.rules b/app-mobilephone/pinephone-meta/files/10-pinephone-brightness.rules
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/10-proximity.rules b/app-mobilephone/pinephone-meta/files/10-proximity.rules
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/20-pinephone-led.rules b/app-mobilephone/pinephone-meta/files/20-pinephone-led.rules
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/90-pinephone.conf b/app-mobilephone/pinephone-meta/files/90-pinephone.conf
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/90-usb-gadget-managed.rules b/app-mobilephone/pinephone-meta/files/90-usb-gadget-managed.rules
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/90_manjaro.gschema.override b/app-mobilephone/pinephone-meta/files/90_manjaro.gschema.override
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/99-automount-sd.rules b/app-mobilephone/pinephone-meta/files/99-automount-sd.rules
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/UserFeedbackConsole.desktop b/app-mobilephone/pinephone-meta/files/UserFeedbackConsole.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/appimagelauncher.desktop b/app-mobilephone/pinephone-meta/files/appimagelauncher.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/appimagelaunchersettings.desktop b/app-mobilephone/pinephone-meta/files/appimagelaunchersettings.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/autoconfig.js b/app-mobilephone/pinephone-meta/files/autoconfig.js
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/avahi-discover.desktop b/app-mobilephone/pinephone-meta/files/avahi-discover.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/bssh.desktop b/app-mobilephone/pinephone-meta/files/bssh.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/bvnc.desktop b/app-mobilephone/pinephone-meta/files/bvnc.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/ca.desrt.dconf-editor.desktop b/app-mobilephone/pinephone-meta/files/ca.desrt.dconf-editor.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/dconf-profile-manjaro b/app-mobilephone/pinephone-meta/files/dconf-profile-manjaro
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/gsk-renderer-gl.sh b/app-mobilephone/pinephone-meta/files/gsk-renderer-gl.sh
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/gtk3-settings.ini b/app-mobilephone/pinephone-meta/files/gtk3-settings.ini
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/ignore-power-key.conf b/app-mobilephone/pinephone-meta/files/ignore-power-key.conf
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/lstopo.desktop b/app-mobilephone/pinephone-meta/files/lstopo.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/machine-info b/app-mobilephone/pinephone-meta/files/machine-info
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/manjaro.cfg b/app-mobilephone/pinephone-meta/files/manjaro.cfg
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/manjaro.json b/app-mobilephone/pinephone-meta/files/manjaro.json
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/media-session.conf b/app-mobilephone/pinephone-meta/files/media-session.conf
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/org.freedesktop.ModemManager1.pkla b/app-mobilephone/pinephone-meta/files/org.freedesktop.ModemManager1.pkla
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/org.gnome.Extensions.desktop b/app-mobilephone/pinephone-meta/files/org.gnome.Extensions.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/org.gnome.Terminal.desktop b/app-mobilephone/pinephone-meta/files/org.gnome.Terminal.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/org.gtk.Demo4.desktop b/app-mobilephone/pinephone-meta/files/org.gtk.Demo4.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/org.gtk.IconBrowser4.desktop b/app-mobilephone/pinephone-meta/files/org.gtk.IconBrowser4.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/org.gtk.PrintEditor4.desktop b/app-mobilephone/pinephone-meta/files/org.gtk.PrintEditor4.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/org.gtk.WidgetFactory4.desktop b/app-mobilephone/pinephone-meta/files/org.gtk.WidgetFactory4.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/packagekit-rm-lock.service b/app-mobilephone/pinephone-meta/files/packagekit-rm-lock.service
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/phosh-renice.service b/app-mobilephone/pinephone-meta/files/phosh-renice.service
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/phosh_renice.sh b/app-mobilephone/pinephone-meta/files/phosh_renice.sh
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/pinephone-camera-setup.service b/app-mobilephone/pinephone-meta/files/pinephone-camera-setup.service
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/pinephone-camera-setup.sh b/app-mobilephone/pinephone-meta/files/pinephone-camera-setup.sh
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/pinephone-manjaro-tweaks.install b/app-mobilephone/pinephone-meta/files/pinephone-manjaro-tweaks.install
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/pinephone-setup-usb-network.service b/app-mobilephone/pinephone-meta/files/pinephone-setup-usb-network.service
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/pinephone-setup-usb-network.sh b/app-mobilephone/pinephone-meta/files/pinephone-setup-usb-network.sh
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/pinephone-suspend-hook.sh b/app-mobilephone/pinephone-meta/files/pinephone-suspend-hook.sh
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/pinephone-usb-gadget.service b/app-mobilephone/pinephone-meta/files/pinephone-usb-gadget.service
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/pinephone-usb-gadget.sh b/app-mobilephone/pinephone-meta/files/pinephone-usb-gadget.sh
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/pinephone.pa b/app-mobilephone/pinephone-meta/files/pinephone.pa
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/qv4l2.desktop b/app-mobilephone/pinephone-meta/files/qv4l2.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/qvidcap.desktop b/app-mobilephone/pinephone-meta/files/qvidcap.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/telegramdesktop.desktop b/app-mobilephone/pinephone-meta/files/telegramdesktop.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/umtp-responder-manjaro.conf b/app-mobilephone/pinephone-meta/files/umtp-responder-manjaro.conf
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/umtp-responder-override.conf b/app-mobilephone/pinephone-meta/files/umtp-responder-override.conf
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/vim.desktop b/app-mobilephone/pinephone-meta/files/vim.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/xgps.desktop b/app-mobilephone/pinephone-meta/files/xgps.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/files/xgpsspeed.desktop b/app-mobilephone/pinephone-meta/files/xgpsspeed.desktop
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/metadata.xml b/app-mobilephone/pinephone-meta/metadata.xml
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-meta/pinephone-meta-0.3.ebuild b/app-mobilephone/pinephone-meta/pinephone-meta-0.3.ebuild
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-modem-scripts/files/90-modem-eg25.rules b/app-mobilephone/pinephone-modem-scripts/files/90-modem-eg25.rules
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-modem-scripts/files/pinephone-modem-scripts.pinephone-modem-setup.service b/app-mobilephone/pinephone-modem-scripts/files/pinephone-modem-scripts.pinephone-modem-setup.service
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-modem-scripts/files/pinephone-modem-setup.sh b/app-mobilephone/pinephone-modem-scripts/files/pinephone-modem-setup.sh
old mode 100644
new mode 100755
diff --git a/app-mobilephone/pinephone-modem-scripts/pinephone-modem-scripts-0.20.8-r3.ebuild b/app-mobilephone/pinephone-modem-scripts/pinephone-modem-scripts-0.20.8-r3.ebuild
old mode 100644
new mode 100755
diff --git a/app-mobilephone/usb-tethering/files/dhcpd.conf b/app-mobilephone/usb-tethering/files/dhcpd.conf
old mode 100644
new mode 100755
diff --git a/app-mobilephone/usb-tethering/files/dhcpd4.service-customexec.conf b/app-mobilephone/usb-tethering/files/dhcpd4.service-customexec.conf
old mode 100644
new mode 100755
diff --git a/app-mobilephone/usb-tethering/files/tmpfiles.d.danctnix-usb.conf b/app-mobilephone/usb-tethering/files/tmpfiles.d.danctnix-usb.conf
old mode 100644
new mode 100755
diff --git a/app-mobilephone/usb-tethering/files/usb-tethering b/app-mobilephone/usb-tethering/files/usb-tethering
old mode 100644
new mode 100755
diff --git a/app-mobilephone/usb-tethering/files/usb-tethering.service b/app-mobilephone/usb-tethering/files/usb-tethering.service
old mode 100644
new mode 100755
diff --git a/app-mobilephone/usb-tethering/metadata.xml b/app-mobilephone/usb-tethering/metadata.xml
old mode 100644
new mode 100755
diff --git a/app-mobilephone/usb-tethering/usb-tethering-0.4.ebuild b/app-mobilephone/usb-tethering/usb-tethering-0.4.ebuild
old mode 100644
new mode 100755
diff --git a/app-text/cmark/Manifest b/app-text/cmark/Manifest
deleted file mode 100644
index d5eca9e..0000000
--- a/app-text/cmark/Manifest
+++ /dev/null
@@ -1 +0,0 @@
-DIST cmark-0.30.2.tar.gz 246033 BLAKE2B 487f5adf47afdd4133e16b6cca1403cd555f8722b47c423960909de73aacac1d0f8b16311f6d5349addb5f03a86562545bb2ec80771b822bb8e5b82816375124 SHA512 aaa9b2103cf89c522f9b42a2b43c07ecf75e07eb42214c0be5de17682ea1faf9c85e3dd28fe91d446b69a34f9980bcab6e276a99b42540c40c9ee1481b3a0d17
diff --git a/app-text/cmark/cmark-0.30.2.ebuild b/app-text/cmark/cmark-0.30.2.ebuild
deleted file mode 100644
index e9ac2bd..0000000
--- a/app-text/cmark/cmark-0.30.2.ebuild
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 1999-2022 Gentoo Authors
-# Distributed under the terms of the GNU General Public License v2
-
-EAPI=8
-
-PYTHON_COMPAT=( python3_{8..10} )
-
-inherit cmake python-any-r1
-
-DESCRIPTION="CommonMark parsing and rendering library and program in C"
-HOMEPAGE="https://github.com/commonmark/cmark"
-SRC_URI="https://github.com/commonmark/cmark/archive/${PV}.tar.gz -> ${P}.tar.gz"
-
-LICENSE="BSD-2"
-SLOT="0/${PV}"
-KEYWORDS="~amd64 ~arm ~arm64 ~ppc ~ppc64 ~riscv ~x86"
-IUSE="test"
-RESTRICT="!test? ( test )"
-
-BDEPEND="test? ( ${PYTHON_DEPS} )"
-
-pkg_setup() {
- use test && python-any-r1_pkg_setup
-}
-
-src_configure() {
- local mycmakeargs=(
- -DCMARK_LIB_FUZZER=OFF
- -DCMARK_SHARED=ON
- -DCMARK_STATIC=OFF
- -DCMARK_TESTS="$(usex test)"
- )
- cmake_src_configure
-}
diff --git a/app-text/cmark/metadata.xml b/app-text/cmark/metadata.xml
deleted file mode 100644
index 931b215..0000000
--- a/app-text/cmark/metadata.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
- azamat.hackimov@gmail.com
- Azamat H. Hackimov
-
-
- proxy-maint@gentoo.org
- Proxy Maintainers
-
-
- commonmark/cmark
-
-
diff --git a/dev-embedded/u-boot-pinephone-pro/u-boot-pinephone-pro-2022.07_rc6.ebuild b/dev-embedded/u-boot-pinephone-pro/u-boot-pinephone-pro-2022.07_rc6.ebuild
index de2b854..4e56680 100755
--- a/dev-embedded/u-boot-pinephone-pro/u-boot-pinephone-pro-2022.07_rc6.ebuild
+++ b/dev-embedded/u-boot-pinephone-pro/u-boot-pinephone-pro-2022.07_rc6.ebuild
@@ -89,6 +89,15 @@ src_compile() {
echo 'CONFIG_SPL_DM_SEQ_ALIAS=" y"' >> .config
echo 'CONFIG_SF_DEFAULT_BUS=" 1"' >> .config
echo 'CONFIG_SPL_MMC_SDHCI_SDMA=" n"' >> .config
+ echo 'CONFIG_SERIAL_PRESENT=" y"' >> .config
+ echo 'CONFIG_GZIP=" y"' >> .config
+ echo 'CONFIG_CMD_UNZIP=" y"' >> .config
+ echo 'CONFIG_CMD_EXT4=" y"' >> .config
+ echo 'CONFIG_SUPPORT_RAW_INITRD=" y"' >> .config
+ echo 'CONFIG_CMD_EXT4_WRITE" n"' >> .config
+ echo 'CONFIG_EXT4_WRITE" n"' >> .config
+ echo 'CONFIG_OF_LIBFDT_OVERLAY=" y"' >> .config
+
emake "${myemakeargs[@]}" EXTRAVERSION=-${PKGREL}
diff --git a/dev-libs/feedbackd/Manifest b/dev-libs/feedbackd/Manifest
old mode 100644
new mode 100755
diff --git a/dev-libs/feedbackd/feedbackd-0.0.0-r2.ebuild b/dev-libs/feedbackd/feedbackd-0.0.0-r2.ebuild
old mode 100644
new mode 100755
diff --git a/dev-libs/feedbackd/files/pine64.pinephone.json b/dev-libs/feedbackd/files/pine64.pinephone.json
old mode 100644
new mode 100755
diff --git a/dev-libs/feedbackd/files/purism.librem5.json b/dev-libs/feedbackd/files/purism.librem5.json
old mode 100644
new mode 100755
diff --git a/dev-libs/feedbackd/metadata.xml b/dev-libs/feedbackd/metadata.xml
old mode 100644
new mode 100755
diff --git a/dev-libs/properties-cpp/Manifest b/dev-libs/properties-cpp/Manifest
old mode 100644
new mode 100755
diff --git a/dev-libs/properties-cpp/metadata.xml b/dev-libs/properties-cpp/metadata.xml
old mode 100644
new mode 100755
diff --git a/dev-libs/properties-cpp/properties-cpp-0.0.2.ebuild b/dev-libs/properties-cpp/properties-cpp-0.0.2.ebuild
old mode 100644
new mode 100755
diff --git a/gnome-extra/iio-sensor-proxy/Manifest b/gnome-extra/iio-sensor-proxy/Manifest
old mode 100644
new mode 100755
diff --git a/gnome-extra/iio-sensor-proxy/iio-sensor-proxy-3.3.ebuild b/gnome-extra/iio-sensor-proxy/iio-sensor-proxy-3.3.ebuild
old mode 100644
new mode 100755
diff --git a/gnome-extra/iio-sensor-proxy/metadata.xml b/gnome-extra/iio-sensor-proxy/metadata.xml
old mode 100644
new mode 100755
diff --git a/gnome-extra/phosh-antispam/Manifest b/gnome-extra/phosh-antispam/Manifest
old mode 100644
new mode 100755
diff --git a/gnome-extra/phosh-antispam/metadata.xml b/gnome-extra/phosh-antispam/metadata.xml
old mode 100644
new mode 100755
diff --git a/gnome-extra/phosh-antispam/phosh-antispam-2.0.ebuild b/gnome-extra/phosh-antispam/phosh-antispam-2.0.ebuild
old mode 100644
new mode 100755
diff --git a/gnome-extra/portfolio/Manifest b/gnome-extra/portfolio/Manifest
old mode 100644
new mode 100755
diff --git a/gnome-extra/portfolio/metadata.xml b/gnome-extra/portfolio/metadata.xml
old mode 100644
new mode 100755
diff --git a/gnome-extra/portfolio/portfolio-0.9.14.ebuild b/gnome-extra/portfolio/portfolio-0.9.14.ebuild
old mode 100644
new mode 100755
diff --git a/gnome-extra/vvmplayer/Manifest b/gnome-extra/vvmplayer/Manifest
old mode 100644
new mode 100755
diff --git a/gnome-extra/vvmplayer/metadata.xml b/gnome-extra/vvmplayer/metadata.xml
old mode 100644
new mode 100755
diff --git a/gnome-extra/vvmplayer/vvmplayer-1.4.ebuild b/gnome-extra/vvmplayer/vvmplayer-1.4.ebuild
old mode 100644
new mode 100755
diff --git a/media-libs/alsa-ucm-pinephone/Manifest b/media-libs/alsa-ucm-pinephone/Manifest
old mode 100644
new mode 100755
diff --git a/media-libs/alsa-ucm-pinephone/alsa-ucm-pinephone-1.2.6.3.ebuild b/media-libs/alsa-ucm-pinephone/alsa-ucm-pinephone-1.2.6.3.ebuild
old mode 100644
new mode 100755
diff --git a/media-libs/alsa-ucm-pinephone/files/PinePhone.conf b/media-libs/alsa-ucm-pinephone/files/PinePhone.conf
old mode 100644
new mode 100755
diff --git a/media-libs/alsa-ucm-pinephone/files/PinePhonePro.conf b/media-libs/alsa-ucm-pinephone/files/PinePhonePro.conf
old mode 100644
new mode 100755
diff --git a/media-libs/alsa-ucm-pinephone/metadata.xml b/media-libs/alsa-ucm-pinephone/metadata.xml
old mode 100644
new mode 100755
diff --git a/media-sound/callaudiod/Manifest b/media-sound/callaudiod/Manifest
old mode 100644
new mode 100755
diff --git a/media-sound/callaudiod/callaudiod-0.1.4.ebuild b/media-sound/callaudiod/callaudiod-0.1.4.ebuild
old mode 100644
new mode 100755
diff --git a/media-sound/callaudiod/metadata.xml b/media-sound/callaudiod/metadata.xml
old mode 100644
new mode 100755
diff --git a/media-video/megapixels/Manifest b/media-video/megapixels/Manifest
old mode 100644
new mode 100755
diff --git a/media-video/megapixels/megapixels-1.4.3.ebuild b/media-video/megapixels/megapixels-1.4.3.ebuild
old mode 100644
new mode 100755
diff --git a/media-video/megapixels/metadata.xml b/media-video/megapixels/metadata.xml
old mode 100644
new mode 100755
diff --git a/metadata/layout.conf b/metadata/layout.conf
old mode 100644
new mode 100755
diff --git a/net-dialup/atinout/Manifest b/net-dialup/atinout/Manifest
old mode 100644
new mode 100755
diff --git a/net-dialup/atinout/atinout-0.9.1-r1.ebuild b/net-dialup/atinout/atinout-0.9.1-r1.ebuild
old mode 100644
new mode 100755
diff --git a/net-dialup/atinout/files/0001-make-gcc-happy-by-adding-fallthrough-comment.patch b/net-dialup/atinout/files/0001-make-gcc-happy-by-adding-fallthrough-comment.patch
old mode 100644
new mode 100755
diff --git a/net-dialup/atinout/files/0002-do-not-rely-on-CR-in-modem-output.patch b/net-dialup/atinout/files/0002-do-not-rely-on-CR-in-modem-output.patch
old mode 100644
new mode 100755
diff --git a/net-dialup/atinout/files/0003-patch-makefile.patch b/net-dialup/atinout/files/0003-patch-makefile.patch
old mode 100644
new mode 100755
diff --git a/net-dialup/atinout/metadata.xml b/net-dialup/atinout/metadata.xml
old mode 100644
new mode 100755
diff --git a/net-im/cawbird/Manifest b/net-im/cawbird/Manifest
old mode 100644
new mode 100755
diff --git a/net-im/cawbird/cawbird-1.5.ebuild b/net-im/cawbird/cawbird-1.5.ebuild
old mode 100644
new mode 100755
diff --git a/net-im/cawbird/metadata.xml b/net-im/cawbird/metadata.xml
old mode 100644
new mode 100755
diff --git a/net-voip/gnome-calls/Manifest b/net-voip/gnome-calls/Manifest
old mode 100644
new mode 100755
diff --git a/net-voip/gnome-calls/gnome-calls-42.0.ebuild b/net-voip/gnome-calls/gnome-calls-42.0.ebuild
old mode 100644
new mode 100755
diff --git a/net-voip/gnome-calls/metadata.xml b/net-voip/gnome-calls/metadata.xml
old mode 100644
new mode 100755
diff --git a/net-voip/vvmd/Manifest b/net-voip/vvmd/Manifest
old mode 100644
new mode 100755
diff --git a/net-voip/vvmd/metadata.xml b/net-voip/vvmd/metadata.xml
old mode 100644
new mode 100755
diff --git a/net-voip/vvmd/vvmd-0.8.ebuild b/net-voip/vvmd/vvmd-0.8.ebuild
old mode 100644
new mode 100755
diff --git a/readme.md b/readme.md
old mode 100644
new mode 100755
diff --git a/sys-kernel/pinephone-pro-sources/Manifest b/sys-kernel/pinephone-pro-sources/Manifest
deleted file mode 100644
index 8c18908..0000000
--- a/sys-kernel/pinephone-pro-sources/Manifest
+++ /dev/null
@@ -1,3 +0,0 @@
-DIST genpatches-5.16-3.base.tar.xz 27568 BLAKE2B 506c36ca597adde1cff11c4a83f1da3dfdc5ec692b932d07fd1e3145291b9f0007ea7fc86c9706ff8b609890b57aa46c224f05c2c3ba3212930bba04b2856d12 SHA512 c740ca5a6820acc94d7aacd03414ce7a9095c6924a3168865dfced1a8eeed3a22039ed5a449571888f16636fc274d6d680748cd919899782bdf02a5460f17823
-DIST genpatches-5.16-3.extras.tar.xz 3780 BLAKE2B 4a4a4c50a4f76363f5701e9166470cca41bc5f34d0f9798eb68cf930d8b9799303553dd127dcd8bc73ba5c4784cf71dcf0c27e77ca146ef9645bc1a0044920cc SHA512 afcb6de6a98390b848708d1b22ea3d8e2f45ad7ed85d64be1f64618b65ca3a21e9011d8a9fb03d83f4630b95bd616507c8c12afcfe1841d032eea7d195ddfcd0
-DIST linux-5.16.tar.xz 123114100 BLAKE2B 07a90cc640ff89e1359c06cee8c38abd33e51f9b9a89833e31a1d2750526fda4a59e8884db3c1ea63df0a37f0d3de6b5a922b014b7313d8abce20d90ac08adcb SHA512 7a257dd576bc8493595ec7d6f3c9cb6e22c772a8b2dbe735d2485c4f5c56e26a08695546e7e0f1f1cd04a533f25e829361958d4da0b98bf0ba8094dd57a85aaf
diff --git a/sys-kernel/pinephone-pro-sources/files/0001-base-property-Swap-order-of-search-for-connection-to.patch b/sys-kernel/pinephone-pro-sources/files/0001-base-property-Swap-order-of-search-for-connection-to.patch
deleted file mode 100644
index 8a3b62c..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0001-base-property-Swap-order-of-search-for-connection-to.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From: Ondrej Jirman
-Date: Mon, 15 Nov 2021 04:09:50 +0100
-Subject: [PATCH 01/36] base: property: Swap order of search for connection to
- "devcon, graph"
-
-This avoids confusing error in kernel log, when using devcon matching
-in DT. Example:
-
-"OF: graph: no port node found in /i2c@ff3d0000/typec-portc@22"
-
-This suggest there's some error because graph based search failed,
-but there is no error, because devcon based matching succeeds.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/base/property.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/base/property.c b/drivers/base/property.c
-index f1f35b4..68cb945 100644
---- a/drivers/base/property.c
-+++ b/drivers/base/property.c
-@@ -1261,10 +1261,10 @@ void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
- if (!fwnode || !match)
- return NULL;
-
-- ret = fwnode_graph_devcon_match(fwnode, con_id, data, match);
-+ ret = fwnode_devcon_match(fwnode, con_id, data, match);
- if (ret)
- return ret;
-
-- return fwnode_devcon_match(fwnode, con_id, data, match);
-+ return fwnode_graph_devcon_match(fwnode, con_id, data, match);
- }
- EXPORT_SYMBOL_GPL(fwnode_connection_find_match);
diff --git a/sys-kernel/pinephone-pro-sources/files/0001-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0001-bootsplash.patch
deleted file mode 100644
index d5835e5..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0001-bootsplash.patch
+++ /dev/null
@@ -1,746 +0,0 @@
-diff --git a/MAINTAINERS b/MAINTAINERS
-index a74227ad082e..b5633b56391e 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -2705,6 +2705,14 @@ S: Supported
- F: drivers/net/bonding/
- F: include/uapi/linux/if_bonding.h
-
-+BOOTSPLASH
-+M: Max Staudt
-+L: linux-fbdev@vger.kernel.org
-+S: Maintained
-+F: drivers/video/fbdev/core/bootsplash*.*
-+F: drivers/video/fbdev/core/dummycon.c
-+F: include/linux/bootsplash.h
-+
- BPF (Safe dynamic programs and tools)
- M: Alexei Starovoitov
- M: Daniel Borkmann
-diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
-index 7f1f1fbcef9e..f3ff976266fe 100644
---- a/drivers/video/console/Kconfig
-+++ b/drivers/video/console/Kconfig
-@@ -151,6 +151,30 @@ config FRAMEBUFFER_CONSOLE_ROTATION
- such that other users of the framebuffer will remain normally
- oriented.
-
-+config BOOTSPLASH
-+ bool "Bootup splash screen"
-+ depends on FRAMEBUFFER_CONSOLE
-+ help
-+ This option enables the Linux bootsplash screen.
-+
-+ The bootsplash is a full-screen logo or animation indicating a
-+ booting system. It replaces the classic scrolling text with a
-+ graphical alternative, similar to other systems.
-+
-+ Since this is technically implemented as a hook on top of fbcon,
-+ it can only work if the FRAMEBUFFER_CONSOLE is enabled and a
-+ framebuffer driver is active. Thus, to get a text-free boot,
-+ the system needs to boot with vesafb, efifb, or similar.
-+
-+ Once built into the kernel, the bootsplash needs to be enabled
-+ with bootsplash.enabled=1 and a splash file needs to be supplied.
-+
-+ Further documentation can be found in:
-+ Documentation/fb/bootsplash.txt
-+
-+ If unsure, say N.
-+ This is typically used by distributors and system integrators.
-+
- config STI_CONSOLE
- bool "STI text console"
- depends on PARISC
-diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
-index 73493bbd7a15..66895321928e 100644
---- a/drivers/video/fbdev/core/Makefile
-+++ b/drivers/video/fbdev/core/Makefile
-@@ -29,3 +29,6 @@ obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
- obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
- obj-$(CONFIG_FB_SVGALIB) += svgalib.o
- obj-$(CONFIG_FB_DDC) += fb_ddc.o
-+
-+obj-$(CONFIG_BOOTSPLASH) += bootsplash.o bootsplash_render.o \
-+ dummyblit.o
-diff --git a/drivers/video/fbdev/core/bootsplash.c b/drivers/video/fbdev/core/bootsplash.c
-new file mode 100644
-index 000000000000..e449755af268
---- /dev/null
-+++ b/drivers/video/fbdev/core/bootsplash.c
-@@ -0,0 +1,294 @@
-+/*
-+ * Kernel based bootsplash.
-+ *
-+ * (Main file: Glue code, workers, timer, PM, kernel and userland API)
-+ *
-+ * Authors:
-+ * Max Staudt
-+ *
-+ * SPDX-License-Identifier: GPL-2.0
-+ */
-+
-+#define pr_fmt(fmt) "bootsplash: " fmt
-+
-+
-+#include
-+#include
-+#include
-+#include /* dev_warn() */
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include /* console_blanked */
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include "bootsplash_internal.h"
-+
-+
-+/*
-+ * We only have one splash screen, so let's keep a single
-+ * instance of the internal state.
-+ */
-+static struct splash_priv splash_state;
-+
-+
-+static void splash_callback_redraw_vc(struct work_struct *ignored)
-+{
-+ if (console_blanked)
-+ return;
-+
-+ console_lock();
-+ if (vc_cons[fg_console].d)
-+ update_screen(vc_cons[fg_console].d);
-+ console_unlock();
-+}
-+
-+
-+static bool is_fb_compatible(const struct fb_info *info)
-+{
-+ if (!(info->flags & FBINFO_BE_MATH)
-+ != !fb_be_math((struct fb_info *)info)) {
-+ dev_warn(info->device,
-+ "Can't draw on foreign endianness framebuffer.\n");
-+
-+ return false;
-+ }
-+
-+ if (info->flags & FBINFO_MISC_TILEBLITTING) {
-+ dev_warn(info->device,
-+ "Can't draw splash on tiling framebuffer.\n");
-+
-+ return false;
-+ }
-+
-+ if (info->fix.type != FB_TYPE_PACKED_PIXELS
-+ || (info->fix.visual != FB_VISUAL_TRUECOLOR
-+ && info->fix.visual != FB_VISUAL_DIRECTCOLOR)) {
-+ dev_warn(info->device,
-+ "Can't draw splash on non-packed or non-truecolor framebuffer.\n");
-+
-+ dev_warn(info->device,
-+ " type: %u visual: %u\n",
-+ info->fix.type, info->fix.visual);
-+
-+ return false;
-+ }
-+
-+ if (info->var.bits_per_pixel != 16
-+ && info->var.bits_per_pixel != 24
-+ && info->var.bits_per_pixel != 32) {
-+ dev_warn(info->device,
-+ "We only support drawing on framebuffers with 16, 24, or 32 bpp, not %d.\n",
-+ info->var.bits_per_pixel);
-+
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+
-+/*
-+ * Called by fbcon_switch() when an instance is activated or refreshed.
-+ */
-+void bootsplash_render_full(struct fb_info *info)
-+{
-+ if (!is_fb_compatible(info))
-+ return;
-+
-+ bootsplash_do_render_background(info);
-+}
-+
-+
-+/*
-+ * External status enquiry and on/off switch
-+ */
-+bool bootsplash_would_render_now(void)
-+{
-+ return !oops_in_progress
-+ && !console_blanked
-+ && bootsplash_is_enabled();
-+}
-+
-+bool bootsplash_is_enabled(void)
-+{
-+ bool was_enabled;
-+
-+ /* Make sure we have the newest state */
-+ smp_rmb();
-+
-+ was_enabled = test_bit(0, &splash_state.enabled);
-+
-+ return was_enabled;
-+}
-+
-+void bootsplash_disable(void)
-+{
-+ int was_enabled;
-+
-+ was_enabled = test_and_clear_bit(0, &splash_state.enabled);
-+
-+ if (was_enabled) {
-+ if (oops_in_progress) {
-+ /* Redraw screen now so we can see a panic */
-+ if (vc_cons[fg_console].d)
-+ update_screen(vc_cons[fg_console].d);
-+ } else {
-+ /* No urgency, redraw at next opportunity */
-+ schedule_work(&splash_state.work_redraw_vc);
-+ }
-+ }
-+}
-+
-+void bootsplash_enable(void)
-+{
-+ bool was_enabled;
-+
-+ if (oops_in_progress)
-+ return;
-+
-+ was_enabled = test_and_set_bit(0, &splash_state.enabled);
-+
-+ if (!was_enabled)
-+ schedule_work(&splash_state.work_redraw_vc);
-+}
-+
-+
-+/*
-+ * Userland API via platform device in sysfs
-+ */
-+static ssize_t splash_show_enabled(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ return sprintf(buf, "%d\n", bootsplash_is_enabled());
-+}
-+
-+static ssize_t splash_store_enabled(struct device *device,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ bool enable;
-+ int err;
-+
-+ if (!buf || !count)
-+ return -EFAULT;
-+
-+ err = kstrtobool(buf, &enable);
-+ if (err)
-+ return err;
-+
-+ if (enable)
-+ bootsplash_enable();
-+ else
-+ bootsplash_disable();
-+
-+ return count;
-+}
-+
-+static DEVICE_ATTR(enabled, 0644, splash_show_enabled, splash_store_enabled);
-+
-+
-+static struct attribute *splash_dev_attrs[] = {
-+ &dev_attr_enabled.attr,
-+ NULL
-+};
-+
-+ATTRIBUTE_GROUPS(splash_dev);
-+
-+
-+
-+
-+/*
-+ * Power management fixup via platform device
-+ *
-+ * When the system is woken from sleep or restored after hibernating, we
-+ * cannot expect the screen contents to still be present in video RAM.
-+ * Thus, we have to redraw the splash if we're currently active.
-+ */
-+static int splash_resume(struct device *device)
-+{
-+ if (bootsplash_would_render_now())
-+ schedule_work(&splash_state.work_redraw_vc);
-+
-+ return 0;
-+}
-+
-+static int splash_suspend(struct device *device)
-+{
-+ cancel_work_sync(&splash_state.work_redraw_vc);
-+
-+ return 0;
-+}
-+
-+
-+static const struct dev_pm_ops splash_pm_ops = {
-+ .thaw = splash_resume,
-+ .restore = splash_resume,
-+ .resume = splash_resume,
-+ .suspend = splash_suspend,
-+ .freeze = splash_suspend,
-+};
-+
-+static struct platform_driver splash_driver = {
-+ .driver = {
-+ .name = "bootsplash",
-+ .pm = &splash_pm_ops,
-+ },
-+};
-+
-+
-+/*
-+ * Main init
-+ */
-+void bootsplash_init(void)
-+{
-+ int ret;
-+
-+ /* Initialized already? */
-+ if (splash_state.splash_device)
-+ return;
-+
-+
-+ /* Register platform device to export user API */
-+ ret = platform_driver_register(&splash_driver);
-+ if (ret) {
-+ pr_err("platform_driver_register() failed: %d\n", ret);
-+ goto err;
-+ }
-+
-+ splash_state.splash_device
-+ = platform_device_alloc("bootsplash", 0);
-+
-+ if (!splash_state.splash_device)
-+ goto err_driver;
-+
-+ splash_state.splash_device->dev.groups = splash_dev_groups;
-+
-+ ret = platform_device_add(splash_state.splash_device);
-+ if (ret) {
-+ pr_err("platform_device_add() failed: %d\n", ret);
-+ goto err_device;
-+ }
-+
-+
-+ INIT_WORK(&splash_state.work_redraw_vc, splash_callback_redraw_vc);
-+
-+ return;
-+
-+err_device:
-+ platform_device_put(splash_state.splash_device);
-+ splash_state.splash_device = NULL;
-+err_driver:
-+ platform_driver_unregister(&splash_driver);
-+err:
-+ pr_err("Failed to initialize.\n");
-+}
-diff --git a/drivers/video/fbdev/core/bootsplash_internal.h b/drivers/video/fbdev/core/bootsplash_internal.h
-new file mode 100644
-index 000000000000..b11da5cb90bf
---- /dev/null
-+++ b/drivers/video/fbdev/core/bootsplash_internal.h
-@@ -0,0 +1,55 @@
-+/*
-+ * Kernel based bootsplash.
-+ *
-+ * (Internal data structures used at runtime)
-+ *
-+ * Authors:
-+ * Max Staudt
-+ *
-+ * SPDX-License-Identifier: GPL-2.0
-+ */
-+
-+#ifndef __BOOTSPLASH_INTERNAL_H
-+#define __BOOTSPLASH_INTERNAL_H
-+
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+
-+/*
-+ * Runtime types
-+ */
-+struct splash_priv {
-+ /*
-+ * Enabled/disabled state, to be used with atomic bit operations.
-+ * Bit 0: 0 = Splash hidden
-+ * 1 = Splash shown
-+ *
-+ * Note: fbcon.c uses this twice, by calling
-+ * bootsplash_would_render_now() in set_blitting_type() and
-+ * in fbcon_switch().
-+ * This is racy, but eventually consistent: Turning the
-+ * splash on/off will cause a redraw, which calls
-+ * fbcon_switch(), which calls set_blitting_type().
-+ * So the last on/off toggle will make things consistent.
-+ */
-+ unsigned long enabled;
-+
-+ /* Our gateway to userland via sysfs */
-+ struct platform_device *splash_device;
-+
-+ struct work_struct work_redraw_vc;
-+};
-+
-+
-+
-+/*
-+ * Rendering functions
-+ */
-+void bootsplash_do_render_background(struct fb_info *info);
-+
-+#endif
-diff --git a/drivers/video/fbdev/core/bootsplash_render.c b/drivers/video/fbdev/core/bootsplash_render.c
-new file mode 100644
-index 000000000000..4d7e0117f653
---- /dev/null
-+++ b/drivers/video/fbdev/core/bootsplash_render.c
-@@ -0,0 +1,93 @@
-+/*
-+ * Kernel based bootsplash.
-+ *
-+ * (Rendering functions)
-+ *
-+ * Authors:
-+ * Max Staudt
-+ *
-+ * SPDX-License-Identifier: GPL-2.0
-+ */
-+
-+#define pr_fmt(fmt) "bootsplash: " fmt
-+
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include "bootsplash_internal.h"
-+
-+
-+
-+
-+/*
-+ * Rendering: Internal drawing routines
-+ */
-+
-+
-+/*
-+ * Pack pixel into target format and do Big/Little Endian handling.
-+ * This would be a good place to handle endianness conversion if necessary.
-+ */
-+static inline u32 pack_pixel(const struct fb_var_screeninfo *dst_var,
-+ u8 red, u8 green, u8 blue)
-+{
-+ u32 dstpix;
-+
-+ /* Quantize pixel */
-+ red = red >> (8 - dst_var->red.length);
-+ green = green >> (8 - dst_var->green.length);
-+ blue = blue >> (8 - dst_var->blue.length);
-+
-+ /* Pack pixel */
-+ dstpix = red << (dst_var->red.offset)
-+ | green << (dst_var->green.offset)
-+ | blue << (dst_var->blue.offset);
-+
-+ /*
-+ * Move packed pixel to the beginning of the memory cell,
-+ * so we can memcpy() it out easily
-+ */
-+#ifdef __BIG_ENDIAN
-+ switch (dst_var->bits_per_pixel) {
-+ case 16:
-+ dstpix <<= 16;
-+ break;
-+ case 24:
-+ dstpix <<= 8;
-+ break;
-+ case 32:
-+ break;
-+ }
-+#else
-+ /* This is intrinsically unnecessary on Little Endian */
-+#endif
-+
-+ return dstpix;
-+}
-+
-+
-+void bootsplash_do_render_background(struct fb_info *info)
-+{
-+ unsigned int x, y;
-+ u32 dstpix;
-+ u32 dst_octpp = info->var.bits_per_pixel / 8;
-+
-+ dstpix = pack_pixel(&info->var,
-+ 0,
-+ 0,
-+ 0);
-+
-+ for (y = 0; y < info->var.yres_virtual; y++) {
-+ u8 *dstline = info->screen_buffer + (y * info->fix.line_length);
-+
-+ for (x = 0; x < info->var.xres_virtual; x++) {
-+ memcpy(dstline, &dstpix, dst_octpp);
-+
-+ dstline += dst_octpp;
-+ }
-+ }
-+}
-diff --git a/drivers/video/fbdev/core/dummyblit.c b/drivers/video/fbdev/core/dummyblit.c
-new file mode 100644
-index 000000000000..8c22ff92ce24
---- /dev/null
-+++ b/drivers/video/fbdev/core/dummyblit.c
-@@ -0,0 +1,89 @@
-+/*
-+ * linux/drivers/video/fbdev/core/dummyblit.c -- Dummy Blitting Operation
-+ *
-+ * Authors:
-+ * Max Staudt
-+ *
-+ * These functions are used in place of blitblit/tileblit to suppress
-+ * fbcon's text output while a splash is shown.
-+ *
-+ * Only suppressing actual rendering keeps the text buffer in the VC layer
-+ * intact and makes it easy to switch back from the bootsplash to a full
-+ * text console with a simple redraw (with the original functions in place).
-+ *
-+ * Based on linux/drivers/video/fbdev/core/bitblit.c
-+ * and linux/drivers/video/fbdev/core/tileblit.c
-+ *
-+ * SPDX-License-Identifier: GPL-2.0
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include "fbcon.h"
-+
-+static void dummy_bmove(struct vc_data *vc, struct fb_info *info, int sy,
-+ int sx, int dy, int dx, int height, int width)
-+{
-+ ;
-+}
-+
-+static void dummy_clear(struct vc_data *vc, struct fb_info *info, int sy,
-+ int sx, int height, int width)
-+{
-+ ;
-+}
-+
-+static void dummy_putcs(struct vc_data *vc, struct fb_info *info,
-+ const unsigned short *s, int count, int yy, int xx,
-+ int fg, int bg)
-+{
-+ ;
-+}
-+
-+static void dummy_clear_margins(struct vc_data *vc, struct fb_info *info,
-+ int color, int bottom_only)
-+{
-+ ;
-+}
-+
-+static void dummy_cursor(struct vc_data *vc, struct fb_info *info, int mode,
-+ int softback_lines, int fg, int bg)
-+{
-+ ;
-+}
-+
-+static int dummy_update_start(struct fb_info *info)
-+{
-+ /*
-+ * Copied from bitblit.c and tileblit.c
-+ *
-+ * As of Linux 4.12, nobody seems to care about our return value.
-+ */
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ int err;
-+
-+ err = fb_pan_display(info, &ops->var);
-+ ops->var.xoffset = info->var.xoffset;
-+ ops->var.yoffset = info->var.yoffset;
-+ ops->var.vmode = info->var.vmode;
-+ return err;
-+}
-+
-+void fbcon_set_dummyops(struct fbcon_ops *ops)
-+{
-+ ops->bmove = dummy_bmove;
-+ ops->clear = dummy_clear;
-+ ops->putcs = dummy_putcs;
-+ ops->clear_margins = dummy_clear_margins;
-+ ops->cursor = dummy_cursor;
-+ ops->update_start = dummy_update_start;
-+ ops->rotate_font = NULL;
-+}
-+EXPORT_SYMBOL_GPL(fbcon_set_dummyops);
-+
-+MODULE_AUTHOR("Max Staudt ");
-+MODULE_DESCRIPTION("Dummy Blitting Operation");
-+MODULE_LICENSE("GPL");
-diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
-index 04612f938bab..9a39a6fcfe98 100644
---- a/drivers/video/fbdev/core/fbcon.c
-+++ b/drivers/video/fbdev/core/fbcon.c
-@@ -80,6 +80,7 @@
- #include
-
- #include "fbcon.h"
-+#include
-
- #ifdef FBCONDEBUG
- # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
-@@ -542,6 +543,8 @@ static int do_fbcon_takeover(int show_logo)
- for (i = first_fb_vc; i <= last_fb_vc; i++)
- con2fb_map[i] = info_idx;
-
-+ bootsplash_init();
-+
- err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc,
- fbcon_is_default);
-
-@@ -661,6 +664,9 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
- else {
- fbcon_set_rotation(info);
- fbcon_set_bitops(ops);
-+
-+ if (bootsplash_would_render_now())
-+ fbcon_set_dummyops(ops);
- }
- }
-
-@@ -683,6 +689,19 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
- ops->p = &fb_display[vc->vc_num];
- fbcon_set_rotation(info);
- fbcon_set_bitops(ops);
-+
-+ /*
-+ * Note:
-+ * This is *eventually correct*.
-+ * Setting the fbcon operations and drawing the splash happen at
-+ * different points in time. If the splash is enabled/disabled
-+ * in between, then bootsplash_{en,dis}able will schedule a
-+ * redraw, which will again render the splash (or not) and set
-+ * the correct fbcon ops.
-+ * The last run will then be the right one.
-+ */
-+ if (bootsplash_would_render_now())
-+ fbcon_set_dummyops(ops);
- }
-
- static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
-@@ -2184,6 +2203,9 @@ static int fbcon_switch(struct vc_data *vc)
- info = registered_fb[con2fb_map[vc->vc_num]];
- ops = info->fbcon_par;
-
-+ if (bootsplash_would_render_now())
-+ bootsplash_render_full(info);
-+
- if (softback_top) {
- if (softback_lines)
- fbcon_set_origin(vc);
-diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
-index 18f3ac144237..45f94347fe5e 100644
---- a/drivers/video/fbdev/core/fbcon.h
-+++ b/drivers/video/fbdev/core/fbcon.h
-@@ -214,6 +214,11 @@ static inline int attr_col_ec(int shift, struct vc_data *vc,
- #define SCROLL_REDRAW 0x004
- #define SCROLL_PAN_REDRAW 0x005
-
-+#ifdef CONFIG_BOOTSPLASH
-+extern void fbcon_set_dummyops(struct fbcon_ops *ops);
-+#else /* CONFIG_BOOTSPLASH */
-+#define fbcon_set_dummyops(x)
-+#endif /* CONFIG_BOOTSPLASH */
- #ifdef CONFIG_FB_TILEBLITTING
- extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
- #endif
-diff --git a/include/linux/bootsplash.h b/include/linux/bootsplash.h
-new file mode 100644
-index 000000000000..c6dd0b43180d
---- /dev/null
-+++ b/include/linux/bootsplash.h
-@@ -0,0 +1,43 @@
-+/*
-+ * Kernel based bootsplash.
-+ *
-+ * Authors:
-+ * Max Staudt
-+ *
-+ * SPDX-License-Identifier: GPL-2.0
-+ */
-+
-+#ifndef __LINUX_BOOTSPLASH_H
-+#define __LINUX_BOOTSPLASH_H
-+
-+#include
-+
-+
-+#ifdef CONFIG_BOOTSPLASH
-+
-+extern void bootsplash_render_full(struct fb_info *info);
-+
-+extern bool bootsplash_would_render_now(void);
-+
-+extern bool bootsplash_is_enabled(void);
-+extern void bootsplash_disable(void);
-+extern void bootsplash_enable(void);
-+
-+extern void bootsplash_init(void);
-+
-+#else /* CONFIG_BOOTSPLASH */
-+
-+#define bootsplash_render_full(x)
-+
-+#define bootsplash_would_render_now() (false)
-+
-+#define bootsplash_is_enabled() (false)
-+#define bootsplash_disable()
-+#define bootsplash_enable()
-+
-+#define bootsplash_init()
-+
-+#endif /* CONFIG_BOOTSPLASH */
-+
-+
-+#endif
diff --git a/sys-kernel/pinephone-pro-sources/files/0001-revert-garbage-collect-fbdev-scrolling-acceleration.patch b/sys-kernel/pinephone-pro-sources/files/0001-revert-garbage-collect-fbdev-scrolling-acceleration.patch
deleted file mode 100644
index 280ed96..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0001-revert-garbage-collect-fbdev-scrolling-acceleration.patch
+++ /dev/null
@@ -1,1038 +0,0 @@
---- b/Documentation/gpu/todo.rst
-+++ a/Documentation/gpu/todo.rst
-@@ -314,19 +314,16 @@
- Garbage collect fbdev scrolling acceleration
- --------------------------------------------
-
-+Scroll acceleration is disabled in fbcon by hard-wiring p->scrollmode =
-+SCROLL_REDRAW. There's a ton of code this will allow us to remove:
--Scroll acceleration has been disabled in fbcon. Now it works as the old
--SCROLL_REDRAW mode. A ton of code was removed in fbcon.c and the hook bmove was
--removed from fbcon_ops.
--Remaining tasks:
-
-+- lots of code in fbcon.c
-+
-+- a bunch of the hooks in fbcon_ops, maybe the remaining hooks could be called
--- a bunch of the hooks in fbcon_ops could be removed or simplified by calling
- directly instead of the function table (with a switch on p->rotate)
-
- - fb_copyarea is unused after this, and can be deleted from all drivers
-
--- after that, fb_copyarea can be deleted from fb_ops in include/linux/fb.h as
-- well as cfb_copyarea
--
- Note that not all acceleration code can be deleted, since clearing and cursor
- support is still accelerated, which might be good candidates for further
- deletion projects.
---- b/drivers/video/fbdev/core/bitblit.c
-+++ a/drivers/video/fbdev/core/bitblit.c
-@@ -43,6 +43,21 @@
- }
- }
-
-+static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
-+ int sx, int dy, int dx, int height, int width)
-+{
-+ struct fb_copyarea area;
-+
-+ area.sx = sx * vc->vc_font.width;
-+ area.sy = sy * vc->vc_font.height;
-+ area.dx = dx * vc->vc_font.width;
-+ area.dy = dy * vc->vc_font.height;
-+ area.height = height * vc->vc_font.height;
-+ area.width = width * vc->vc_font.width;
-+
-+ info->fbops->fb_copyarea(info, &area);
-+}
-+
- static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
- int sx, int height, int width)
- {
-@@ -378,6 +393,7 @@
-
- void fbcon_set_bitops(struct fbcon_ops *ops)
- {
-+ ops->bmove = bit_bmove;
- ops->clear = bit_clear;
- ops->putcs = bit_putcs;
- ops->clear_margins = bit_clear_margins;
---- b/drivers/video/fbdev/core/fbcon.c
-+++ a/drivers/video/fbdev/core/fbcon.c
-@@ -173,6 +173,8 @@
- int count, int ypos, int xpos);
- static void fbcon_clear_margins(struct vc_data *vc, int bottom_only);
- static void fbcon_cursor(struct vc_data *vc, int mode);
-+static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
-+ int height, int width);
- static int fbcon_switch(struct vc_data *vc);
- static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch);
- static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table);
-@@ -180,8 +182,16 @@
- /*
- * Internal routines
- */
-+static __inline__ void ywrap_up(struct vc_data *vc, int count);
-+static __inline__ void ywrap_down(struct vc_data *vc, int count);
-+static __inline__ void ypan_up(struct vc_data *vc, int count);
-+static __inline__ void ypan_down(struct vc_data *vc, int count);
-+static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx,
-+ int dy, int dx, int height, int width, u_int y_break);
- static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
- int unit);
-+static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
-+ int line, int count, int dy);
- static void fbcon_modechanged(struct fb_info *info);
- static void fbcon_set_all_vcs(struct fb_info *info);
- static void fbcon_start(void);
-@@ -1125,6 +1135,14 @@
-
- ops->graphics = 0;
-
-+ /*
-+ * No more hw acceleration for fbcon.
-+ *
-+ * FIXME: Garbage collect all the now dead code after sufficient time
-+ * has passed.
-+ */
-+ p->scrollmode = SCROLL_REDRAW;
-+
- /*
- * ++guenther: console.c:vc_allocate() relies on initializing
- * vc_{cols,rows}, but we must not set those if we are only
-@@ -1211,13 +1229,14 @@
- * This system is now divided into two levels because of complications
- * caused by hardware scrolling. Top level functions:
- *
-+ * fbcon_bmove(), fbcon_clear(), fbcon_putc(), fbcon_clear_margins()
-- * fbcon_clear(), fbcon_putc(), fbcon_clear_margins()
- *
- * handles y values in range [0, scr_height-1] that correspond to real
- * screen positions. y_wrap shift means that first line of bitmap may be
- * anywhere on this display. These functions convert lineoffsets to
- * bitmap offsets and deal with the wrap-around case by splitting blits.
- *
-+ * fbcon_bmove_physical_8() -- These functions fast implementations
- * fbcon_clear_physical_8() -- of original fbcon_XXX fns.
- * fbcon_putc_physical_8() -- (font width != 8) may be added later
- *
-@@ -1390,6 +1409,224 @@
- }
- }
-
-+static __inline__ void ywrap_up(struct vc_data *vc, int count)
-+{
-+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ struct fbcon_display *p = &fb_display[vc->vc_num];
-+
-+ p->yscroll += count;
-+ if (p->yscroll >= p->vrows) /* Deal with wrap */
-+ p->yscroll -= p->vrows;
-+ ops->var.xoffset = 0;
-+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
-+ ops->var.vmode |= FB_VMODE_YWRAP;
-+ ops->update_start(info);
-+ scrollback_max += count;
-+ if (scrollback_max > scrollback_phys_max)
-+ scrollback_max = scrollback_phys_max;
-+ scrollback_current = 0;
-+}
-+
-+static __inline__ void ywrap_down(struct vc_data *vc, int count)
-+{
-+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ struct fbcon_display *p = &fb_display[vc->vc_num];
-+
-+ p->yscroll -= count;
-+ if (p->yscroll < 0) /* Deal with wrap */
-+ p->yscroll += p->vrows;
-+ ops->var.xoffset = 0;
-+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
-+ ops->var.vmode |= FB_VMODE_YWRAP;
-+ ops->update_start(info);
-+ scrollback_max -= count;
-+ if (scrollback_max < 0)
-+ scrollback_max = 0;
-+ scrollback_current = 0;
-+}
-+
-+static __inline__ void ypan_up(struct vc_data *vc, int count)
-+{
-+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
-+ struct fbcon_display *p = &fb_display[vc->vc_num];
-+ struct fbcon_ops *ops = info->fbcon_par;
-+
-+ p->yscroll += count;
-+ if (p->yscroll > p->vrows - vc->vc_rows) {
-+ ops->bmove(vc, info, p->vrows - vc->vc_rows,
-+ 0, 0, 0, vc->vc_rows, vc->vc_cols);
-+ p->yscroll -= p->vrows - vc->vc_rows;
-+ }
-+
-+ ops->var.xoffset = 0;
-+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
-+ ops->var.vmode &= ~FB_VMODE_YWRAP;
-+ ops->update_start(info);
-+ fbcon_clear_margins(vc, 1);
-+ scrollback_max += count;
-+ if (scrollback_max > scrollback_phys_max)
-+ scrollback_max = scrollback_phys_max;
-+ scrollback_current = 0;
-+}
-+
-+static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
-+{
-+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ struct fbcon_display *p = &fb_display[vc->vc_num];
-+
-+ p->yscroll += count;
-+
-+ if (p->yscroll > p->vrows - vc->vc_rows) {
-+ p->yscroll -= p->vrows - vc->vc_rows;
-+ fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
-+ }
-+
-+ ops->var.xoffset = 0;
-+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
-+ ops->var.vmode &= ~FB_VMODE_YWRAP;
-+ ops->update_start(info);
-+ fbcon_clear_margins(vc, 1);
-+ scrollback_max += count;
-+ if (scrollback_max > scrollback_phys_max)
-+ scrollback_max = scrollback_phys_max;
-+ scrollback_current = 0;
-+}
-+
-+static __inline__ void ypan_down(struct vc_data *vc, int count)
-+{
-+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
-+ struct fbcon_display *p = &fb_display[vc->vc_num];
-+ struct fbcon_ops *ops = info->fbcon_par;
-+
-+ p->yscroll -= count;
-+ if (p->yscroll < 0) {
-+ ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
-+ 0, vc->vc_rows, vc->vc_cols);
-+ p->yscroll += p->vrows - vc->vc_rows;
-+ }
-+
-+ ops->var.xoffset = 0;
-+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
-+ ops->var.vmode &= ~FB_VMODE_YWRAP;
-+ ops->update_start(info);
-+ fbcon_clear_margins(vc, 1);
-+ scrollback_max -= count;
-+ if (scrollback_max < 0)
-+ scrollback_max = 0;
-+ scrollback_current = 0;
-+}
-+
-+static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
-+{
-+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ struct fbcon_display *p = &fb_display[vc->vc_num];
-+
-+ p->yscroll -= count;
-+
-+ if (p->yscroll < 0) {
-+ p->yscroll += p->vrows - vc->vc_rows;
-+ fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
-+ }
-+
-+ ops->var.xoffset = 0;
-+ ops->var.yoffset = p->yscroll * vc->vc_font.height;
-+ ops->var.vmode &= ~FB_VMODE_YWRAP;
-+ ops->update_start(info);
-+ fbcon_clear_margins(vc, 1);
-+ scrollback_max -= count;
-+ if (scrollback_max < 0)
-+ scrollback_max = 0;
-+ scrollback_current = 0;
-+}
-+
-+static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
-+ int line, int count, int dy)
-+{
-+ unsigned short *s = (unsigned short *)
-+ (vc->vc_origin + vc->vc_size_row * line);
-+
-+ while (count--) {
-+ unsigned short *start = s;
-+ unsigned short *le = advance_row(s, 1);
-+ unsigned short c;
-+ int x = 0;
-+ unsigned short attr = 1;
-+
-+ do {
-+ c = scr_readw(s);
-+ if (attr != (c & 0xff00)) {
-+ attr = c & 0xff00;
-+ if (s > start) {
-+ fbcon_putcs(vc, start, s - start,
-+ dy, x);
-+ x += s - start;
-+ start = s;
-+ }
-+ }
-+ console_conditional_schedule();
-+ s++;
-+ } while (s < le);
-+ if (s > start)
-+ fbcon_putcs(vc, start, s - start, dy, x);
-+ console_conditional_schedule();
-+ dy++;
-+ }
-+}
-+
-+static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,
-+ struct fbcon_display *p, int line, int count, int ycount)
-+{
-+ int offset = ycount * vc->vc_cols;
-+ unsigned short *d = (unsigned short *)
-+ (vc->vc_origin + vc->vc_size_row * line);
-+ unsigned short *s = d + offset;
-+ struct fbcon_ops *ops = info->fbcon_par;
-+
-+ while (count--) {
-+ unsigned short *start = s;
-+ unsigned short *le = advance_row(s, 1);
-+ unsigned short c;
-+ int x = 0;
-+
-+ do {
-+ c = scr_readw(s);
-+
-+ if (c == scr_readw(d)) {
-+ if (s > start) {
-+ ops->bmove(vc, info, line + ycount, x,
-+ line, x, 1, s-start);
-+ x += s - start + 1;
-+ start = s + 1;
-+ } else {
-+ x++;
-+ start++;
-+ }
-+ }
-+
-+ scr_writew(c, d);
-+ console_conditional_schedule();
-+ s++;
-+ d++;
-+ } while (s < le);
-+ if (s > start)
-+ ops->bmove(vc, info, line + ycount, x, line, x, 1,
-+ s-start);
-+ console_conditional_schedule();
-+ if (ycount > 0)
-+ line++;
-+ else {
-+ line--;
-+ /* NOTE: We subtract two lines from these pointers */
-+ s -= vc->vc_size_row;
-+ d -= vc->vc_size_row;
-+ }
-+ }
-+}
-+
- static void fbcon_redraw(struct vc_data *vc, struct fbcon_display *p,
- int line, int count, int offset)
- {
-@@ -1450,6 +1687,7 @@
- {
- struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
- struct fbcon_display *p = &fb_display[vc->vc_num];
-+ int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
-
- if (fbcon_is_inactive(vc, info))
- return true;
-@@ -1466,32 +1704,249 @@
- case SM_UP:
- if (count > vc->vc_rows) /* Maximum realistic size */
- count = vc->vc_rows;
-+ if (logo_shown >= 0)
-+ goto redraw_up;
-+ switch (p->scrollmode) {
-+ case SCROLL_MOVE:
-+ fbcon_redraw_blit(vc, info, p, t, b - t - count,
-+ count);
-+ fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
-+ scr_memsetw((unsigned short *) (vc->vc_origin +
-+ vc->vc_size_row *
-+ (b - count)),
-+ vc->vc_video_erase_char,
-+ vc->vc_size_row * count);
-+ return true;
-+
-+ case SCROLL_WRAP_MOVE:
-+ if (b - t - count > 3 * vc->vc_rows >> 2) {
-+ if (t > 0)
-+ fbcon_bmove(vc, 0, 0, count, 0, t,
-+ vc->vc_cols);
-+ ywrap_up(vc, count);
-+ if (vc->vc_rows - b > 0)
-+ fbcon_bmove(vc, b - count, 0, b, 0,
-+ vc->vc_rows - b,
-+ vc->vc_cols);
-+ } else if (info->flags & FBINFO_READS_FAST)
-+ fbcon_bmove(vc, t + count, 0, t, 0,
-+ b - t - count, vc->vc_cols);
-+ else
-+ goto redraw_up;
-+ fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
-+ break;
-+
-+ case SCROLL_PAN_REDRAW:
-+ if ((p->yscroll + count <=
-+ 2 * (p->vrows - vc->vc_rows))
-+ && ((!scroll_partial && (b - t == vc->vc_rows))
-+ || (scroll_partial
-+ && (b - t - count >
-+ 3 * vc->vc_rows >> 2)))) {
-+ if (t > 0)
-+ fbcon_redraw_move(vc, p, 0, t, count);
-+ ypan_up_redraw(vc, t, count);
-+ if (vc->vc_rows - b > 0)
-+ fbcon_redraw_move(vc, p, b,
-+ vc->vc_rows - b, b);
-+ } else
-+ fbcon_redraw_move(vc, p, t + count, b - t - count, t);
-+ fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
-+ break;
-+
-+ case SCROLL_PAN_MOVE:
-+ if ((p->yscroll + count <=
-+ 2 * (p->vrows - vc->vc_rows))
-+ && ((!scroll_partial && (b - t == vc->vc_rows))
-+ || (scroll_partial
-+ && (b - t - count >
-+ 3 * vc->vc_rows >> 2)))) {
-+ if (t > 0)
-+ fbcon_bmove(vc, 0, 0, count, 0, t,
-+ vc->vc_cols);
-+ ypan_up(vc, count);
-+ if (vc->vc_rows - b > 0)
-+ fbcon_bmove(vc, b - count, 0, b, 0,
-+ vc->vc_rows - b,
-+ vc->vc_cols);
-+ } else if (info->flags & FBINFO_READS_FAST)
-+ fbcon_bmove(vc, t + count, 0, t, 0,
-+ b - t - count, vc->vc_cols);
-+ else
-+ goto redraw_up;
-+ fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
-+ break;
-+
-+ case SCROLL_REDRAW:
-+ redraw_up:
-+ fbcon_redraw(vc, p, t, b - t - count,
-+ count * vc->vc_cols);
-+ fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
-+ scr_memsetw((unsigned short *) (vc->vc_origin +
-+ vc->vc_size_row *
-+ (b - count)),
-+ vc->vc_video_erase_char,
-+ vc->vc_size_row * count);
-+ return true;
-+ }
-+ break;
-- fbcon_redraw(vc, p, t, b - t - count,
-- count * vc->vc_cols);
-- fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
-- scr_memsetw((unsigned short *) (vc->vc_origin +
-- vc->vc_size_row *
-- (b - count)),
-- vc->vc_video_erase_char,
-- vc->vc_size_row * count);
-- return true;
-
- case SM_DOWN:
- if (count > vc->vc_rows) /* Maximum realistic size */
- count = vc->vc_rows;
-+ if (logo_shown >= 0)
-+ goto redraw_down;
-+ switch (p->scrollmode) {
-+ case SCROLL_MOVE:
-+ fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
-+ -count);
-+ fbcon_clear(vc, t, 0, count, vc->vc_cols);
-+ scr_memsetw((unsigned short *) (vc->vc_origin +
-+ vc->vc_size_row *
-+ t),
-+ vc->vc_video_erase_char,
-+ vc->vc_size_row * count);
-+ return true;
-+
-+ case SCROLL_WRAP_MOVE:
-+ if (b - t - count > 3 * vc->vc_rows >> 2) {
-+ if (vc->vc_rows - b > 0)
-+ fbcon_bmove(vc, b, 0, b - count, 0,
-+ vc->vc_rows - b,
-+ vc->vc_cols);
-+ ywrap_down(vc, count);
-+ if (t > 0)
-+ fbcon_bmove(vc, count, 0, 0, 0, t,
-+ vc->vc_cols);
-+ } else if (info->flags & FBINFO_READS_FAST)
-+ fbcon_bmove(vc, t, 0, t + count, 0,
-+ b - t - count, vc->vc_cols);
-+ else
-+ goto redraw_down;
-+ fbcon_clear(vc, t, 0, count, vc->vc_cols);
-+ break;
-+
-+ case SCROLL_PAN_MOVE:
-+ if ((count - p->yscroll <= p->vrows - vc->vc_rows)
-+ && ((!scroll_partial && (b - t == vc->vc_rows))
-+ || (scroll_partial
-+ && (b - t - count >
-+ 3 * vc->vc_rows >> 2)))) {
-+ if (vc->vc_rows - b > 0)
-+ fbcon_bmove(vc, b, 0, b - count, 0,
-+ vc->vc_rows - b,
-+ vc->vc_cols);
-+ ypan_down(vc, count);
-+ if (t > 0)
-+ fbcon_bmove(vc, count, 0, 0, 0, t,
-+ vc->vc_cols);
-+ } else if (info->flags & FBINFO_READS_FAST)
-+ fbcon_bmove(vc, t, 0, t + count, 0,
-+ b - t - count, vc->vc_cols);
-+ else
-+ goto redraw_down;
-+ fbcon_clear(vc, t, 0, count, vc->vc_cols);
-+ break;
-+
-+ case SCROLL_PAN_REDRAW:
-+ if ((count - p->yscroll <= p->vrows - vc->vc_rows)
-+ && ((!scroll_partial && (b - t == vc->vc_rows))
-+ || (scroll_partial
-+ && (b - t - count >
-+ 3 * vc->vc_rows >> 2)))) {
-+ if (vc->vc_rows - b > 0)
-+ fbcon_redraw_move(vc, p, b, vc->vc_rows - b,
-+ b - count);
-+ ypan_down_redraw(vc, t, count);
-+ if (t > 0)
-+ fbcon_redraw_move(vc, p, count, t, 0);
-+ } else
-+ fbcon_redraw_move(vc, p, t, b - t - count, t + count);
-+ fbcon_clear(vc, t, 0, count, vc->vc_cols);
-+ break;
-+
-+ case SCROLL_REDRAW:
-+ redraw_down:
-+ fbcon_redraw(vc, p, b - 1, b - t - count,
-+ -count * vc->vc_cols);
-+ fbcon_clear(vc, t, 0, count, vc->vc_cols);
-+ scr_memsetw((unsigned short *) (vc->vc_origin +
-+ vc->vc_size_row *
-+ t),
-+ vc->vc_video_erase_char,
-+ vc->vc_size_row * count);
-+ return true;
-+ }
-- fbcon_redraw(vc, p, b - 1, b - t - count,
-- -count * vc->vc_cols);
-- fbcon_clear(vc, t, 0, count, vc->vc_cols);
-- scr_memsetw((unsigned short *) (vc->vc_origin +
-- vc->vc_size_row *
-- t),
-- vc->vc_video_erase_char,
-- vc->vc_size_row * count);
-- return true;
- }
- return false;
- }
-
-+
-+static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
-+ int height, int width)
-+{
-+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
-+ struct fbcon_display *p = &fb_display[vc->vc_num];
-+
-+ if (fbcon_is_inactive(vc, info))
-+ return;
-+
-+ if (!width || !height)
-+ return;
-+
-+ /* Split blits that cross physical y_wrap case.
-+ * Pathological case involves 4 blits, better to use recursive
-+ * code rather than unrolled case
-+ *
-+ * Recursive invocations don't need to erase the cursor over and
-+ * over again, so we use fbcon_bmove_rec()
-+ */
-+ fbcon_bmove_rec(vc, p, sy, sx, dy, dx, height, width,
-+ p->vrows - p->yscroll);
-+}
-+
-+static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx,
-+ int dy, int dx, int height, int width, u_int y_break)
-+{
-+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ u_int b;
-+
-+ if (sy < y_break && sy + height > y_break) {
-+ b = y_break - sy;
-+ if (dy < sy) { /* Avoid trashing self */
-+ fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
-+ y_break);
-+ fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
-+ height - b, width, y_break);
-+ } else {
-+ fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
-+ height - b, width, y_break);
-+ fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
-+ y_break);
-+ }
-+ return;
-+ }
-+
-+ if (dy < y_break && dy + height > y_break) {
-+ b = y_break - dy;
-+ if (dy < sy) { /* Avoid trashing self */
-+ fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
-+ y_break);
-+ fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
-+ height - b, width, y_break);
-+ } else {
-+ fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
-+ height - b, width, y_break);
-+ fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
-+ y_break);
-+ }
-+ return;
-+ }
-+ ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
-+ height, width);
-+}
-+
- static void updatescrollmode(struct fbcon_display *p,
- struct fb_info *info,
- struct vc_data *vc)
-@@ -1664,7 +2119,21 @@
-
- updatescrollmode(p, info, vc);
-
-+ switch (p->scrollmode) {
-+ case SCROLL_WRAP_MOVE:
-+ scrollback_phys_max = p->vrows - vc->vc_rows;
-+ break;
-+ case SCROLL_PAN_MOVE:
-+ case SCROLL_PAN_REDRAW:
-+ scrollback_phys_max = p->vrows - 2 * vc->vc_rows;
-+ if (scrollback_phys_max < 0)
-+ scrollback_phys_max = 0;
-+ break;
-+ default:
-+ scrollback_phys_max = 0;
-+ break;
-+ }
-+
-- scrollback_phys_max = 0;
- scrollback_max = 0;
- scrollback_current = 0;
-
---- b/drivers/video/fbdev/core/fbcon.h
-+++ a/drivers/video/fbdev/core/fbcon.h
-@@ -29,6 +29,7 @@
- /* Filled in by the low-level console driver */
- const u_char *fontdata;
- int userfont; /* != 0 if fontdata kmalloc()ed */
-+ u_short scrollmode; /* Scroll Method */
- u_short inverse; /* != 0 text black on white as default */
- short yscroll; /* Hardware scrolling */
- int vrows; /* number of virtual rows */
-@@ -51,6 +52,8 @@
- };
-
- struct fbcon_ops {
-+ void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
-+ int sx, int dy, int dx, int height, int width);
- void (*clear)(struct vc_data *vc, struct fb_info *info, int sy,
- int sx, int height, int width);
- void (*putcs)(struct vc_data *vc, struct fb_info *info,
-@@ -149,6 +152,62 @@
- #define attr_bgcol_ec(bgshift, vc, info) attr_col_ec(bgshift, vc, info, 0)
- #define attr_fgcol_ec(fgshift, vc, info) attr_col_ec(fgshift, vc, info, 1)
-
-+ /*
-+ * Scroll Method
-+ */
-+
-+/* There are several methods fbcon can use to move text around the screen:
-+ *
-+ * Operation Pan Wrap
-+ *---------------------------------------------
-+ * SCROLL_MOVE copyarea No No
-+ * SCROLL_PAN_MOVE copyarea Yes No
-+ * SCROLL_WRAP_MOVE copyarea No Yes
-+ * SCROLL_REDRAW imageblit No No
-+ * SCROLL_PAN_REDRAW imageblit Yes No
-+ * SCROLL_WRAP_REDRAW imageblit No Yes
-+ *
-+ * (SCROLL_WRAP_REDRAW is not implemented yet)
-+ *
-+ * In general, fbcon will choose the best scrolling
-+ * method based on the rule below:
-+ *
-+ * Pan/Wrap > accel imageblit > accel copyarea >
-+ * soft imageblit > (soft copyarea)
-+ *
-+ * Exception to the rule: Pan + accel copyarea is
-+ * preferred over Pan + accel imageblit.
-+ *
-+ * The above is typical for PCI/AGP cards. Unless
-+ * overridden, fbcon will never use soft copyarea.
-+ *
-+ * If you need to override the above rule, set the
-+ * appropriate flags in fb_info->flags. For example,
-+ * to prefer copyarea over imageblit, set
-+ * FBINFO_READS_FAST.
-+ *
-+ * Other notes:
-+ * + use the hardware engine to move the text
-+ * (hw-accelerated copyarea() and fillrect())
-+ * + use hardware-supported panning on a large virtual screen
-+ * + amifb can not only pan, but also wrap the display by N lines
-+ * (i.e. visible line i = physical line (i+N) % yres).
-+ * + read what's already rendered on the screen and
-+ * write it in a different place (this is cfb_copyarea())
-+ * + re-render the text to the screen
-+ *
-+ * Whether to use wrapping or panning can only be figured out at
-+ * runtime (when we know whether our font height is a multiple
-+ * of the pan/wrap step)
-+ *
-+ */
-+
-+#define SCROLL_MOVE 0x001
-+#define SCROLL_PAN_MOVE 0x002
-+#define SCROLL_WRAP_MOVE 0x003
-+#define SCROLL_REDRAW 0x004
-+#define SCROLL_PAN_REDRAW 0x005
-+
- #ifdef CONFIG_FB_TILEBLITTING
- extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
- #endif
---- b/drivers/video/fbdev/core/fbcon_ccw.c
-+++ a/drivers/video/fbdev/core/fbcon_ccw.c
-@@ -59,12 +59,31 @@
- }
- }
-
-+
-+static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
-+ int sx, int dy, int dx, int height, int width)
-+{
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ struct fb_copyarea area;
-+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
-+
-+ area.sx = sy * vc->vc_font.height;
-+ area.sy = vyres - ((sx + width) * vc->vc_font.width);
-+ area.dx = dy * vc->vc_font.height;
-+ area.dy = vyres - ((dx + width) * vc->vc_font.width);
-+ area.width = height * vc->vc_font.height;
-+ area.height = width * vc->vc_font.width;
-+
-+ info->fbops->fb_copyarea(info, &area);
-+}
-+
- static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
- int sx, int height, int width)
- {
-+ struct fbcon_ops *ops = info->fbcon_par;
- struct fb_fillrect region;
- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
-+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
-- u32 vyres = info->var.yres;
-
- region.color = attr_bgcol_ec(bgshift,vc,info);
- region.dx = sy * vc->vc_font.height;
-@@ -121,7 +140,7 @@
- u32 cnt, pitch, size;
- u32 attribute = get_attribute(info, scr_readw(s));
- u8 *dst, *buf = NULL;
-+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
-- u32 vyres = info->var.yres;
-
- if (!ops->fontbuffer)
- return;
-@@ -210,7 +229,7 @@
- int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
- int err = 1, dx, dy;
- char *src;
-+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
-- u32 vyres = info->var.yres;
-
- if (!ops->fontbuffer)
- return;
-@@ -368,7 +387,7 @@
- {
- struct fbcon_ops *ops = info->fbcon_par;
- u32 yoffset;
-+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
-- u32 vyres = info->var.yres;
- int err;
-
- yoffset = (vyres - info->var.yres) - ops->var.xoffset;
-@@ -383,6 +402,7 @@
-
- void fbcon_rotate_ccw(struct fbcon_ops *ops)
- {
-+ ops->bmove = ccw_bmove;
- ops->clear = ccw_clear;
- ops->putcs = ccw_putcs;
- ops->clear_margins = ccw_clear_margins;
---- b/drivers/video/fbdev/core/fbcon_cw.c
-+++ a/drivers/video/fbdev/core/fbcon_cw.c
-@@ -44,12 +44,31 @@
- }
- }
-
-+
-+static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
-+ int sx, int dy, int dx, int height, int width)
-+{
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ struct fb_copyarea area;
-+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
-+
-+ area.sx = vxres - ((sy + height) * vc->vc_font.height);
-+ area.sy = sx * vc->vc_font.width;
-+ area.dx = vxres - ((dy + height) * vc->vc_font.height);
-+ area.dy = dx * vc->vc_font.width;
-+ area.width = height * vc->vc_font.height;
-+ area.height = width * vc->vc_font.width;
-+
-+ info->fbops->fb_copyarea(info, &area);
-+}
-+
- static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
- int sx, int height, int width)
- {
-+ struct fbcon_ops *ops = info->fbcon_par;
- struct fb_fillrect region;
- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
-+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
-- u32 vxres = info->var.xres;
-
- region.color = attr_bgcol_ec(bgshift,vc,info);
- region.dx = vxres - ((sy + height) * vc->vc_font.height);
-@@ -106,7 +125,7 @@
- u32 cnt, pitch, size;
- u32 attribute = get_attribute(info, scr_readw(s));
- u8 *dst, *buf = NULL;
-+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
-- u32 vxres = info->var.xres;
-
- if (!ops->fontbuffer)
- return;
-@@ -193,7 +212,7 @@
- int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
- int err = 1, dx, dy;
- char *src;
-+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
-- u32 vxres = info->var.xres;
-
- if (!ops->fontbuffer)
- return;
-@@ -350,7 +369,7 @@
- static int cw_update_start(struct fb_info *info)
- {
- struct fbcon_ops *ops = info->fbcon_par;
-+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
-- u32 vxres = info->var.xres;
- u32 xoffset;
- int err;
-
-@@ -366,6 +385,7 @@
-
- void fbcon_rotate_cw(struct fbcon_ops *ops)
- {
-+ ops->bmove = cw_bmove;
- ops->clear = cw_clear;
- ops->putcs = cw_putcs;
- ops->clear_margins = cw_clear_margins;
---- b/drivers/video/fbdev/core/fbcon_rotate.h
-+++ a/drivers/video/fbdev/core/fbcon_rotate.h
-@@ -11,6 +11,15 @@
- #ifndef _FBCON_ROTATE_H
- #define _FBCON_ROTATE_H
-
-+#define GETVYRES(s,i) ({ \
-+ (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
-+ (i)->var.yres : (i)->var.yres_virtual; })
-+
-+#define GETVXRES(s,i) ({ \
-+ (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
-+ (i)->var.xres : (i)->var.xres_virtual; })
-+
-+
- static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
- {
- u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
---- b/drivers/video/fbdev/core/fbcon_ud.c
-+++ a/drivers/video/fbdev/core/fbcon_ud.c
-@@ -44,13 +44,33 @@
- }
- }
-
-+
-+static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
-+ int sx, int dy, int dx, int height, int width)
-+{
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ struct fb_copyarea area;
-+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
-+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
-+
-+ area.sy = vyres - ((sy + height) * vc->vc_font.height);
-+ area.sx = vxres - ((sx + width) * vc->vc_font.width);
-+ area.dy = vyres - ((dy + height) * vc->vc_font.height);
-+ area.dx = vxres - ((dx + width) * vc->vc_font.width);
-+ area.height = height * vc->vc_font.height;
-+ area.width = width * vc->vc_font.width;
-+
-+ info->fbops->fb_copyarea(info, &area);
-+}
-+
- static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
- int sx, int height, int width)
- {
-+ struct fbcon_ops *ops = info->fbcon_par;
- struct fb_fillrect region;
- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
-+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
-+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
-- u32 vyres = info->var.yres;
-- u32 vxres = info->var.xres;
-
- region.color = attr_bgcol_ec(bgshift,vc,info);
- region.dy = vyres - ((sy + height) * vc->vc_font.height);
-@@ -142,8 +162,8 @@
- u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
- u32 attribute = get_attribute(info, scr_readw(s));
- u8 *dst, *buf = NULL;
-+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
-+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
-- u32 vyres = info->var.yres;
-- u32 vxres = info->var.xres;
-
- if (!ops->fontbuffer)
- return;
-@@ -239,8 +259,8 @@
- int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
- int err = 1, dx, dy;
- char *src;
-+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
-+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
-- u32 vyres = info->var.yres;
-- u32 vxres = info->var.xres;
-
- if (!ops->fontbuffer)
- return;
-@@ -390,8 +410,8 @@
- {
- struct fbcon_ops *ops = info->fbcon_par;
- int xoffset, yoffset;
-+ u32 vyres = GETVYRES(ops->p->scrollmode, info);
-+ u32 vxres = GETVXRES(ops->p->scrollmode, info);
-- u32 vyres = info->var.yres;
-- u32 vxres = info->var.xres;
- int err;
-
- xoffset = vxres - info->var.xres - ops->var.xoffset;
-@@ -409,6 +429,7 @@
-
- void fbcon_rotate_ud(struct fbcon_ops *ops)
- {
-+ ops->bmove = ud_bmove;
- ops->clear = ud_clear;
- ops->putcs = ud_putcs;
- ops->clear_margins = ud_clear_margins;
---- b/drivers/video/fbdev/core/tileblit.c
-+++ a/drivers/video/fbdev/core/tileblit.c
-@@ -16,6 +16,21 @@
- #include
- #include "fbcon.h"
-
-+static void tile_bmove(struct vc_data *vc, struct fb_info *info, int sy,
-+ int sx, int dy, int dx, int height, int width)
-+{
-+ struct fb_tilearea area;
-+
-+ area.sx = sx;
-+ area.sy = sy;
-+ area.dx = dx;
-+ area.dy = dy;
-+ area.height = height;
-+ area.width = width;
-+
-+ info->tileops->fb_tilecopy(info, &area);
-+}
-+
- static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy,
- int sx, int height, int width)
- {
-@@ -118,6 +133,7 @@
- struct fb_tilemap map;
- struct fbcon_ops *ops = info->fbcon_par;
-
-+ ops->bmove = tile_bmove;
- ops->clear = tile_clear;
- ops->putcs = tile_putcs;
- ops->clear_margins = tile_clear_margins;
---- b/drivers/video/fbdev/skeletonfb.c
-+++ a/drivers/video/fbdev/skeletonfb.c
-@@ -505,15 +505,15 @@
- }
-
- /**
-+ * xxxfb_copyarea - REQUIRED function. Can use generic routines if
-+ * non acclerated hardware and packed pixel based.
-- * xxxfb_copyarea - OBSOLETE function.
- * Copies one area of the screen to another area.
-- * Will be deleted in a future version
- *
- * @info: frame buffer structure that represents a single frame buffer
- * @area: Structure providing the data to copy the framebuffer contents
- * from one region to another.
- *
-+ * This drawing operation copies a rectangular area from one area of the
-- * This drawing operation copied a rectangular area from one area of the
- * screen to another area.
- */
- void xxxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
-@@ -645,9 +645,9 @@
- .fb_setcolreg = xxxfb_setcolreg,
- .fb_blank = xxxfb_blank,
- .fb_pan_display = xxxfb_pan_display,
-+ .fb_fillrect = xxxfb_fillrect, /* Needed !!! */
-+ .fb_copyarea = xxxfb_copyarea, /* Needed !!! */
-+ .fb_imageblit = xxxfb_imageblit, /* Needed !!! */
-- .fb_fillrect = xxxfb_fillrect, /* Needed !!! */
-- .fb_copyarea = xxxfb_copyarea, /* Obsolete */
-- .fb_imageblit = xxxfb_imageblit, /* Needed !!! */
- .fb_cursor = xxxfb_cursor, /* Optional !!! */
- .fb_sync = xxxfb_sync,
- .fb_ioctl = xxxfb_ioctl,
---- b/include/linux/fb.h
-+++ a/include/linux/fb.h
-@@ -262,7 +262,7 @@
-
- /* Draws a rectangle */
- void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
-+ /* Copy data from area to another */
-- /* Copy data from area to another. Obsolete. */
- void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
- /* Draws a image to the display */
- void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
diff --git a/sys-kernel/pinephone-pro-sources/files/0002-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0002-bootsplash.patch
deleted file mode 100644
index 92d62ca..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0002-bootsplash.patch
+++ /dev/null
@@ -1,669 +0,0 @@
-diff --git a/MAINTAINERS b/MAINTAINERS
-index b5633b56391e..5c237445761e 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -2712,6 +2712,7 @@ S: Maintained
- F: drivers/video/fbdev/core/bootsplash*.*
- F: drivers/video/fbdev/core/dummycon.c
- F: include/linux/bootsplash.h
-+F: include/uapi/linux/bootsplash_file.h
-
- BPF (Safe dynamic programs and tools)
- M: Alexei Starovoitov
-diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
-index 66895321928e..6a8d1bab8a01 100644
---- a/drivers/video/fbdev/core/Makefile
-+++ b/drivers/video/fbdev/core/Makefile
-@@ -31,4 +31,4 @@ obj-$(CONFIG_FB_SVGALIB) += svgalib.o
- obj-$(CONFIG_FB_DDC) += fb_ddc.o
-
- obj-$(CONFIG_BOOTSPLASH) += bootsplash.o bootsplash_render.o \
-- dummyblit.o
-+ bootsplash_load.o dummyblit.o
-diff --git a/drivers/video/fbdev/core/bootsplash.c b/drivers/video/fbdev/core/bootsplash.c
-index e449755af268..843c5400fefc 100644
---- a/drivers/video/fbdev/core/bootsplash.c
-+++ b/drivers/video/fbdev/core/bootsplash.c
-@@ -32,6 +32,7 @@
- #include
-
- #include "bootsplash_internal.h"
-+#include "uapi/linux/bootsplash_file.h"
-
-
- /*
-@@ -102,10 +103,17 @@ static bool is_fb_compatible(const struct fb_info *info)
- */
- void bootsplash_render_full(struct fb_info *info)
- {
-+ mutex_lock(&splash_state.data_lock);
-+
- if (!is_fb_compatible(info))
-- return;
-+ goto out;
-+
-+ bootsplash_do_render_background(info, splash_state.file);
-+
-+ bootsplash_do_render_pictures(info, splash_state.file);
-
-- bootsplash_do_render_background(info);
-+out:
-+ mutex_unlock(&splash_state.data_lock);
- }
-
-
-@@ -116,6 +124,7 @@ bool bootsplash_would_render_now(void)
- {
- return !oops_in_progress
- && !console_blanked
-+ && splash_state.file
- && bootsplash_is_enabled();
- }
-
-@@ -252,6 +261,7 @@ static struct platform_driver splash_driver = {
- void bootsplash_init(void)
- {
- int ret;
-+ struct splash_file_priv *fp;
-
- /* Initialized already? */
- if (splash_state.splash_device)
-@@ -280,8 +290,26 @@ void bootsplash_init(void)
- }
-
-
-+ mutex_init(&splash_state.data_lock);
-+ set_bit(0, &splash_state.enabled);
-+
- INIT_WORK(&splash_state.work_redraw_vc, splash_callback_redraw_vc);
-
-+
-+ if (!splash_state.bootfile || !strlen(splash_state.bootfile))
-+ return;
-+
-+ fp = bootsplash_load_firmware(&splash_state.splash_device->dev,
-+ splash_state.bootfile);
-+
-+ if (!fp)
-+ goto err;
-+
-+ mutex_lock(&splash_state.data_lock);
-+ splash_state.splash_fb = NULL;
-+ splash_state.file = fp;
-+ mutex_unlock(&splash_state.data_lock);
-+
- return;
-
- err_device:
-@@ -292,3 +320,7 @@ void bootsplash_init(void)
- err:
- pr_err("Failed to initialize.\n");
- }
-+
-+
-+module_param_named(bootfile, splash_state.bootfile, charp, 0444);
-+MODULE_PARM_DESC(bootfile, "Bootsplash file to load on boot");
-diff --git a/drivers/video/fbdev/core/bootsplash_internal.h b/drivers/video/fbdev/core/bootsplash_internal.h
-index b11da5cb90bf..71e2a27ac0b8 100644
---- a/drivers/video/fbdev/core/bootsplash_internal.h
-+++ b/drivers/video/fbdev/core/bootsplash_internal.h
-@@ -15,15 +15,43 @@
-
- #include
- #include
-+#include
- #include
- #include
- #include
-
-+#include "uapi/linux/bootsplash_file.h"
-+
-
- /*
- * Runtime types
- */
-+struct splash_blob_priv {
-+ struct splash_blob_header *blob_header;
-+ const void *data;
-+};
-+
-+
-+struct splash_pic_priv {
-+ const struct splash_pic_header *pic_header;
-+
-+ struct splash_blob_priv *blobs;
-+ u16 blobs_loaded;
-+};
-+
-+
-+struct splash_file_priv {
-+ const struct firmware *fw;
-+ const struct splash_file_header *header;
-+
-+ struct splash_pic_priv *pics;
-+};
-+
-+
- struct splash_priv {
-+ /* Bootup and runtime state */
-+ char *bootfile;
-+
- /*
- * Enabled/disabled state, to be used with atomic bit operations.
- * Bit 0: 0 = Splash hidden
-@@ -43,6 +71,13 @@ struct splash_priv {
- struct platform_device *splash_device;
-
- struct work_struct work_redraw_vc;
-+
-+ /* Splash data structures including lock for everything below */
-+ struct mutex data_lock;
-+
-+ struct fb_info *splash_fb;
-+
-+ struct splash_file_priv *file;
- };
-
-
-@@ -50,6 +85,14 @@ struct splash_priv {
- /*
- * Rendering functions
- */
--void bootsplash_do_render_background(struct fb_info *info);
-+void bootsplash_do_render_background(struct fb_info *info,
-+ const struct splash_file_priv *fp);
-+void bootsplash_do_render_pictures(struct fb_info *info,
-+ const struct splash_file_priv *fp);
-+
-+
-+void bootsplash_free_file(struct splash_file_priv *fp);
-+struct splash_file_priv *bootsplash_load_firmware(struct device *device,
-+ const char *path);
-
- #endif
-diff --git a/drivers/video/fbdev/core/bootsplash_load.c b/drivers/video/fbdev/core/bootsplash_load.c
-new file mode 100644
-index 000000000000..fd807571ab7d
---- /dev/null
-+++ b/drivers/video/fbdev/core/bootsplash_load.c
-@@ -0,0 +1,225 @@
-+/*
-+ * Kernel based bootsplash.
-+ *
-+ * (Loading and freeing functions)
-+ *
-+ * Authors:
-+ * Max Staudt
-+ *
-+ * SPDX-License-Identifier: GPL-2.0
-+ */
-+
-+#define pr_fmt(fmt) "bootsplash: " fmt
-+
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include "bootsplash_internal.h"
-+#include "uapi/linux/bootsplash_file.h"
-+
-+
-+
-+
-+/*
-+ * Free all vmalloc()'d resources describing a splash file.
-+ */
-+void bootsplash_free_file(struct splash_file_priv *fp)
-+{
-+ if (!fp)
-+ return;
-+
-+ if (fp->pics) {
-+ unsigned int i;
-+
-+ for (i = 0; i < fp->header->num_pics; i++) {
-+ struct splash_pic_priv *pp = &fp->pics[i];
-+
-+ if (pp->blobs)
-+ vfree(pp->blobs);
-+ }
-+
-+ vfree(fp->pics);
-+ }
-+
-+ release_firmware(fp->fw);
-+ vfree(fp);
-+}
-+
-+
-+
-+
-+/*
-+ * Load a splash screen from a "firmware" file.
-+ *
-+ * Parsing, and sanity checks.
-+ */
-+#ifdef __BIG_ENDIAN
-+ #define BOOTSPLASH_MAGIC BOOTSPLASH_MAGIC_BE
-+#else
-+ #define BOOTSPLASH_MAGIC BOOTSPLASH_MAGIC_LE
-+#endif
-+
-+struct splash_file_priv *bootsplash_load_firmware(struct device *device,
-+ const char *path)
-+{
-+ const struct firmware *fw;
-+ struct splash_file_priv *fp;
-+ unsigned int i;
-+ const u8 *walker;
-+
-+ if (request_firmware(&fw, path, device))
-+ return NULL;
-+
-+ if (fw->size < sizeof(struct splash_file_header)
-+ || memcmp(fw->data, BOOTSPLASH_MAGIC, sizeof(fp->header->id))) {
-+ pr_err("Not a bootsplash file.\n");
-+
-+ release_firmware(fw);
-+ return NULL;
-+ }
-+
-+ fp = vzalloc(sizeof(struct splash_file_priv));
-+ if (!fp) {
-+ release_firmware(fw);
-+ return NULL;
-+ }
-+
-+ pr_info("Loading splash file (%li bytes)\n", fw->size);
-+
-+ fp->fw = fw;
-+ fp->header = (struct splash_file_header *)fw->data;
-+
-+ /* Sanity checks */
-+ if (fp->header->version != BOOTSPLASH_VERSION) {
-+ pr_err("Loaded v%d file, but we only support version %d\n",
-+ fp->header->version,
-+ BOOTSPLASH_VERSION);
-+
-+ goto err;
-+ }
-+
-+ if (fw->size < sizeof(struct splash_file_header)
-+ + fp->header->num_pics
-+ * sizeof(struct splash_pic_header)
-+ + fp->header->num_blobs
-+ * sizeof(struct splash_blob_header)) {
-+ pr_err("File incomplete.\n");
-+
-+ goto err;
-+ }
-+
-+ /* Read picture headers */
-+ if (fp->header->num_pics) {
-+ fp->pics = vzalloc(fp->header->num_pics
-+ * sizeof(struct splash_pic_priv));
-+ if (!fp->pics)
-+ goto err;
-+ }
-+
-+ walker = fw->data + sizeof(struct splash_file_header);
-+ for (i = 0; i < fp->header->num_pics; i++) {
-+ struct splash_pic_priv *pp = &fp->pics[i];
-+ struct splash_pic_header *ph = (void *)walker;
-+
-+ pr_debug("Picture %u: Size %ux%u\n", i, ph->width, ph->height);
-+
-+ if (ph->num_blobs < 1) {
-+ pr_err("Picture %u: Zero blobs? Aborting load.\n", i);
-+ goto err;
-+ }
-+
-+ pp->pic_header = ph;
-+ pp->blobs = vzalloc(ph->num_blobs
-+ * sizeof(struct splash_blob_priv));
-+ if (!pp->blobs)
-+ goto err;
-+
-+ walker += sizeof(struct splash_pic_header);
-+ }
-+
-+ /* Read blob headers */
-+ for (i = 0; i < fp->header->num_blobs; i++) {
-+ struct splash_blob_header *bh = (void *)walker;
-+ struct splash_pic_priv *pp;
-+
-+ if (walker + sizeof(struct splash_blob_header)
-+ > fw->data + fw->size)
-+ goto err;
-+
-+ walker += sizeof(struct splash_blob_header);
-+
-+ if (walker + bh->length > fw->data + fw->size)
-+ goto err;
-+
-+ if (bh->picture_id >= fp->header->num_pics)
-+ goto nextblob;
-+
-+ pp = &fp->pics[bh->picture_id];
-+
-+ pr_debug("Blob %u, pic %u, blobs_loaded %u, num_blobs %u.\n",
-+ i, bh->picture_id,
-+ pp->blobs_loaded, pp->pic_header->num_blobs);
-+
-+ if (pp->blobs_loaded >= pp->pic_header->num_blobs)
-+ goto nextblob;
-+
-+ switch (bh->type) {
-+ case 0:
-+ /* Raw 24-bit packed pixels */
-+ if (bh->length != pp->pic_header->width
-+ * pp->pic_header->height * 3) {
-+ pr_err("Blob %u, type 1: Length doesn't match picture.\n",
-+ i);
-+
-+ goto err;
-+ }
-+ break;
-+ default:
-+ pr_warn("Blob %u, unknown type %u.\n", i, bh->type);
-+ goto nextblob;
-+ }
-+
-+ pp->blobs[pp->blobs_loaded].blob_header = bh;
-+ pp->blobs[pp->blobs_loaded].data = walker;
-+ pp->blobs_loaded++;
-+
-+nextblob:
-+ walker += bh->length;
-+ if (bh->length % 16)
-+ walker += 16 - (bh->length % 16);
-+ }
-+
-+ if (walker != fw->data + fw->size)
-+ pr_warn("Trailing data in splash file.\n");
-+
-+ /* Walk over pictures and ensure all blob slots are filled */
-+ for (i = 0; i < fp->header->num_pics; i++) {
-+ struct splash_pic_priv *pp = &fp->pics[i];
-+
-+ if (pp->blobs_loaded != pp->pic_header->num_blobs) {
-+ pr_err("Picture %u doesn't have all blob slots filled.\n",
-+ i);
-+
-+ goto err;
-+ }
-+ }
-+
-+ pr_info("Loaded (%ld bytes, %u pics, %u blobs).\n",
-+ fw->size,
-+ fp->header->num_pics,
-+ fp->header->num_blobs);
-+
-+ return fp;
-+
-+
-+err:
-+ bootsplash_free_file(fp);
-+ return NULL;
-+}
-diff --git a/drivers/video/fbdev/core/bootsplash_render.c b/drivers/video/fbdev/core/bootsplash_render.c
-index 4d7e0117f653..2ae36949d0e3 100644
---- a/drivers/video/fbdev/core/bootsplash_render.c
-+++ b/drivers/video/fbdev/core/bootsplash_render.c
-@@ -19,6 +19,7 @@
- #include
-
- #include "bootsplash_internal.h"
-+#include "uapi/linux/bootsplash_file.h"
-
-
-
-@@ -70,16 +71,69 @@ static inline u32 pack_pixel(const struct fb_var_screeninfo *dst_var,
- }
-
-
--void bootsplash_do_render_background(struct fb_info *info)
-+/*
-+ * Copy from source and blend into the destination picture.
-+ * Currently assumes that the source picture is 24bpp.
-+ * Currently assumes that the destination is <= 32bpp.
-+ */
-+static int splash_convert_to_fb(u8 *dst,
-+ const struct fb_var_screeninfo *dst_var,
-+ unsigned int dst_stride,
-+ unsigned int dst_xoff,
-+ unsigned int dst_yoff,
-+ const u8 *src,
-+ unsigned int src_width,
-+ unsigned int src_height)
-+{
-+ unsigned int x, y;
-+ unsigned int src_stride = 3 * src_width; /* Assume 24bpp packed */
-+ u32 dst_octpp = dst_var->bits_per_pixel / 8;
-+
-+ dst_xoff += dst_var->xoffset;
-+ dst_yoff += dst_var->yoffset;
-+
-+ /* Copy with stride and pixel size adjustment */
-+ for (y = 0;
-+ y < src_height && y + dst_yoff < dst_var->yres_virtual;
-+ y++) {
-+ const u8 *srcline = src + (y * src_stride);
-+ u8 *dstline = dst + ((y + dst_yoff) * dst_stride)
-+ + (dst_xoff * dst_octpp);
-+
-+ for (x = 0;
-+ x < src_width && x + dst_xoff < dst_var->xres_virtual;
-+ x++) {
-+ u8 red, green, blue;
-+ u32 dstpix;
-+
-+ /* Read pixel */
-+ red = *srcline++;
-+ green = *srcline++;
-+ blue = *srcline++;
-+
-+ /* Write pixel */
-+ dstpix = pack_pixel(dst_var, red, green, blue);
-+ memcpy(dstline, &dstpix, dst_octpp);
-+
-+ dstline += dst_octpp;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+
-+void bootsplash_do_render_background(struct fb_info *info,
-+ const struct splash_file_priv *fp)
- {
- unsigned int x, y;
- u32 dstpix;
- u32 dst_octpp = info->var.bits_per_pixel / 8;
-
- dstpix = pack_pixel(&info->var,
-- 0,
-- 0,
-- 0);
-+ fp->header->bg_red,
-+ fp->header->bg_green,
-+ fp->header->bg_blue);
-
- for (y = 0; y < info->var.yres_virtual; y++) {
- u8 *dstline = info->screen_buffer + (y * info->fix.line_length);
-@@ -91,3 +145,44 @@ void bootsplash_do_render_background(struct fb_info *info)
- }
- }
- }
-+
-+
-+void bootsplash_do_render_pictures(struct fb_info *info,
-+ const struct splash_file_priv *fp)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < fp->header->num_pics; i++) {
-+ struct splash_blob_priv *bp;
-+ struct splash_pic_priv *pp = &fp->pics[i];
-+ long dst_xoff, dst_yoff;
-+
-+ if (pp->blobs_loaded < 1)
-+ continue;
-+
-+ bp = &pp->blobs[0];
-+
-+ if (!bp || bp->blob_header->type != 0)
-+ continue;
-+
-+ dst_xoff = (info->var.xres - pp->pic_header->width) / 2;
-+ dst_yoff = (info->var.yres - pp->pic_header->height) / 2;
-+
-+ if (dst_xoff < 0
-+ || dst_yoff < 0
-+ || dst_xoff + pp->pic_header->width > info->var.xres
-+ || dst_yoff + pp->pic_header->height > info->var.yres) {
-+ pr_info_once("Picture %u is out of bounds at current resolution: %dx%d\n"
-+ "(this will only be printed once every reboot)\n",
-+ i, info->var.xres, info->var.yres);
-+
-+ continue;
-+ }
-+
-+ /* Draw next splash frame */
-+ splash_convert_to_fb(info->screen_buffer, &info->var,
-+ info->fix.line_length, dst_xoff, dst_yoff,
-+ bp->data,
-+ pp->pic_header->width, pp->pic_header->height);
-+ }
-+}
-diff --git a/include/uapi/linux/bootsplash_file.h b/include/uapi/linux/bootsplash_file.h
-new file mode 100644
-index 000000000000..89dc9cca8f0c
---- /dev/null
-+++ b/include/uapi/linux/bootsplash_file.h
-@@ -0,0 +1,118 @@
-+/*
-+ * Kernel based bootsplash.
-+ *
-+ * (File format)
-+ *
-+ * Authors:
-+ * Max Staudt
-+ *
-+ * SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
-+ */
-+
-+#ifndef __BOOTSPLASH_FILE_H
-+#define __BOOTSPLASH_FILE_H
-+
-+
-+#define BOOTSPLASH_VERSION 55561
-+
-+
-+#include
-+#include
-+
-+
-+/*
-+ * On-disk types
-+ *
-+ * A splash file consists of:
-+ * - One single 'struct splash_file_header'
-+ * - An array of 'struct splash_pic_header'
-+ * - An array of raw data blocks, each padded to 16 bytes and
-+ * preceded by a 'struct splash_blob_header'
-+ *
-+ * A single-frame splash may look like this:
-+ *
-+ * +--------------------+
-+ * | |
-+ * | splash_file_header |
-+ * | -> num_blobs = 1 |
-+ * | -> num_pics = 1 |
-+ * | |
-+ * +--------------------+
-+ * | |
-+ * | splash_pic_header |
-+ * | |
-+ * +--------------------+
-+ * | |
-+ * | splash_blob_header |
-+ * | -> type = 0 |
-+ * | -> picture_id = 0 |
-+ * | |
-+ * | (raw RGB data) |
-+ * | (pad to 16 bytes) |
-+ * | |
-+ * +--------------------+
-+ *
-+ * All multi-byte values are stored on disk in the native format
-+ * expected by the system the file will be used on.
-+ */
-+#define BOOTSPLASH_MAGIC_BE "Linux bootsplash"
-+#define BOOTSPLASH_MAGIC_LE "hsalpstoob xuniL"
-+
-+struct splash_file_header {
-+ uint8_t id[16]; /* "Linux bootsplash" (no trailing NUL) */
-+
-+ /* Splash file format version to avoid clashes */
-+ uint16_t version;
-+
-+ /* The background color */
-+ uint8_t bg_red;
-+ uint8_t bg_green;
-+ uint8_t bg_blue;
-+ uint8_t bg_reserved;
-+
-+ /*
-+ * Number of pic/blobs so we can allocate memory for internal
-+ * structures ahead of time when reading the file
-+ */
-+ uint16_t num_blobs;
-+ uint8_t num_pics;
-+
-+ uint8_t padding[103];
-+} __attribute__((__packed__));
-+
-+
-+struct splash_pic_header {
-+ uint16_t width;
-+ uint16_t height;
-+
-+ /*
-+ * Number of data packages associated with this picture.
-+ * Currently, the only use for more than 1 is for animations.
-+ */
-+ uint8_t num_blobs;
-+
-+ uint8_t padding[27];
-+} __attribute__((__packed__));
-+
-+
-+struct splash_blob_header {
-+ /* Length of the data block in bytes. */
-+ uint32_t length;
-+
-+ /*
-+ * Type of the contents.
-+ * 0 - Raw RGB data.
-+ */
-+ uint16_t type;
-+
-+ /*
-+ * Picture this blob is associated with.
-+ * Blobs will be added to a picture in the order they are
-+ * found in the file.
-+ */
-+ uint8_t picture_id;
-+
-+ uint8_t padding[9];
-+} __attribute__((__packed__));
-+
-+#endif
diff --git a/sys-kernel/pinephone-pro-sources/files/0002-clk-rk3399-Export-SCLK_CIF_OUT_SRC-to-device-tree.patch b/sys-kernel/pinephone-pro-sources/files/0002-clk-rk3399-Export-SCLK_CIF_OUT_SRC-to-device-tree.patch
deleted file mode 100644
index fd8585a..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0002-clk-rk3399-Export-SCLK_CIF_OUT_SRC-to-device-tree.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Ondrej Jirman
-Date: Fri, 22 Oct 2021 18:09:09 +0200
-Subject: [PATCH 19/36] clk: rk3399: Export SCLK_CIF_OUT_SRC to device tree
-
-So that it can be used in assigned-clock-parents.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/clk/rockchip/clk-rk3399.c | 2 +-
- include/dt-bindings/clock/rk3399-cru.h | 1 +
- 2 files changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
-index 306910a..897581e 100644
---- a/drivers/clk/rockchip/clk-rk3399.c
-+++ b/drivers/clk/rockchip/clk-rk3399.c
-@@ -1259,7 +1259,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
- RK3399_CLKGATE_CON(27), 6, GFLAGS),
-
- /* cif */
-- COMPOSITE_NODIV(0, "clk_cifout_src", mux_pll_src_cpll_gpll_npll_p, 0,
-+ COMPOSITE_NODIV(SCLK_CIF_OUT_SRC, "clk_cifout_src", mux_pll_src_cpll_gpll_npll_p, 0,
- RK3399_CLKSEL_CON(56), 6, 2, MFLAGS,
- RK3399_CLKGATE_CON(10), 7, GFLAGS),
-
-diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
-index 44e0a31..e83b3fb 100644
---- a/include/dt-bindings/clock/rk3399-cru.h
-+++ b/include/dt-bindings/clock/rk3399-cru.h
-@@ -125,6 +125,7 @@
- #define SCLK_DDRC 168
- #define SCLK_TESTCLKOUT1 169
- #define SCLK_TESTCLKOUT2 170
-+#define SCLK_CIF_OUT_SRC 171
-
- #define DCLK_VOP0 180
- #define DCLK_VOP1 181
diff --git a/sys-kernel/pinephone-pro-sources/files/0002-revert-fbcon-remove-now-unusued-softback_lines-cursor-argument.patch b/sys-kernel/pinephone-pro-sources/files/0002-revert-fbcon-remove-now-unusued-softback_lines-cursor-argument.patch
deleted file mode 100644
index e7d4da5..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0002-revert-fbcon-remove-now-unusued-softback_lines-cursor-argument.patch
+++ /dev/null
@@ -1,150 +0,0 @@
---- b/drivers/video/fbdev/core/bitblit.c
-+++ a/drivers/video/fbdev/core/bitblit.c
-@@ -234,7 +234,7 @@
- }
-
- static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
-+ int softback_lines, int fg, int bg)
-- int fg, int bg)
- {
- struct fb_cursor cursor;
- struct fbcon_ops *ops = info->fbcon_par;
-@@ -247,6 +247,15 @@
-
- cursor.set = 0;
-
-+ if (softback_lines) {
-+ if (y + softback_lines >= vc->vc_rows) {
-+ mode = CM_ERASE;
-+ ops->cursor_flash = 0;
-+ return;
-+ } else
-+ y += softback_lines;
-+ }
-+
- c = scr_readw((u16 *) vc->vc_pos);
- attribute = get_attribute(info, c);
- src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
---- b/drivers/video/fbdev/core/fbcon.c
-+++ a/drivers/video/fbdev/core/fbcon.c
-@@ -394,7 +394,7 @@
- c = scr_readw((u16 *) vc->vc_pos);
- mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
- CM_ERASE : CM_DRAW;
-+ ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1),
-- ops->cursor(vc, info, mode, get_color(vc, info, c, 1),
- get_color(vc, info, c, 0));
- console_unlock();
- }
-@@ -1345,7 +1345,7 @@
-
- ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
-
-+ ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1),
-- ops->cursor(vc, info, mode, get_color(vc, info, c, 1),
- get_color(vc, info, c, 0));
- }
-
---- b/drivers/video/fbdev/core/fbcon.h
-+++ a/drivers/video/fbdev/core/fbcon.h
-@@ -62,7 +62,7 @@
- void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
- int color, int bottom_only);
- void (*cursor)(struct vc_data *vc, struct fb_info *info, int mode,
-+ int softback_lines, int fg, int bg);
-- int fg, int bg);
- int (*update_start)(struct fb_info *info);
- int (*rotate_font)(struct fb_info *info, struct vc_data *vc);
- struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
---- b/drivers/video/fbdev/core/fbcon_ccw.c
-+++ a/drivers/video/fbdev/core/fbcon_ccw.c
-@@ -219,7 +219,7 @@
- }
-
- static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
-+ int softback_lines, int fg, int bg)
-- int fg, int bg)
- {
- struct fb_cursor cursor;
- struct fbcon_ops *ops = info->fbcon_par;
-@@ -236,6 +236,15 @@
-
- cursor.set = 0;
-
-+ if (softback_lines) {
-+ if (y + softback_lines >= vc->vc_rows) {
-+ mode = CM_ERASE;
-+ ops->cursor_flash = 0;
-+ return;
-+ } else
-+ y += softback_lines;
-+ }
-+
- c = scr_readw((u16 *) vc->vc_pos);
- attribute = get_attribute(info, c);
- src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
---- b/drivers/video/fbdev/core/fbcon_cw.c
-+++ a/drivers/video/fbdev/core/fbcon_cw.c
-@@ -202,7 +202,7 @@
- }
-
- static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
-+ int softback_lines, int fg, int bg)
-- int fg, int bg)
- {
- struct fb_cursor cursor;
- struct fbcon_ops *ops = info->fbcon_par;
-@@ -219,6 +219,15 @@
-
- cursor.set = 0;
-
-+ if (softback_lines) {
-+ if (y + softback_lines >= vc->vc_rows) {
-+ mode = CM_ERASE;
-+ ops->cursor_flash = 0;
-+ return;
-+ } else
-+ y += softback_lines;
-+ }
-+
- c = scr_readw((u16 *) vc->vc_pos);
- attribute = get_attribute(info, c);
- src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
---- b/drivers/video/fbdev/core/fbcon_ud.c
-+++ a/drivers/video/fbdev/core/fbcon_ud.c
-@@ -249,7 +249,7 @@
- }
-
- static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
-+ int softback_lines, int fg, int bg)
-- int fg, int bg)
- {
- struct fb_cursor cursor;
- struct fbcon_ops *ops = info->fbcon_par;
-@@ -267,6 +267,15 @@
-
- cursor.set = 0;
-
-+ if (softback_lines) {
-+ if (y + softback_lines >= vc->vc_rows) {
-+ mode = CM_ERASE;
-+ ops->cursor_flash = 0;
-+ return;
-+ } else
-+ y += softback_lines;
-+ }
-+
- c = scr_readw((u16 *) vc->vc_pos);
- attribute = get_attribute(info, c);
- src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
---- b/drivers/video/fbdev/core/tileblit.c
-+++ a/drivers/video/fbdev/core/tileblit.c
-@@ -80,7 +80,7 @@
- }
-
- static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
-+ int softback_lines, int fg, int bg)
-- int fg, int bg)
- {
- struct fb_tilecursor cursor;
- int use_sw = (vc->vc_cursor_type & 0x10);
diff --git a/sys-kernel/pinephone-pro-sources/files/0003-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0003-bootsplash.patch
deleted file mode 100644
index 2169537..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0003-bootsplash.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-diff --git a/drivers/video/fbdev/core/bootsplash.c b/drivers/video/fbdev/core/bootsplash.c
-index 843c5400fefc..815b007f81ca 100644
---- a/drivers/video/fbdev/core/bootsplash.c
-+++ b/drivers/video/fbdev/core/bootsplash.c
-@@ -112,6 +112,8 @@ void bootsplash_render_full(struct fb_info *info)
-
- bootsplash_do_render_pictures(info, splash_state.file);
-
-+ bootsplash_do_render_flush(info);
-+
- out:
- mutex_unlock(&splash_state.data_lock);
- }
-diff --git a/drivers/video/fbdev/core/bootsplash_internal.h b/drivers/video/fbdev/core/bootsplash_internal.h
-index 71e2a27ac0b8..0acb383aa4e3 100644
---- a/drivers/video/fbdev/core/bootsplash_internal.h
-+++ b/drivers/video/fbdev/core/bootsplash_internal.h
-@@ -89,6 +89,7 @@ void bootsplash_do_render_background(struct fb_info *info,
- const struct splash_file_priv *fp);
- void bootsplash_do_render_pictures(struct fb_info *info,
- const struct splash_file_priv *fp);
-+void bootsplash_do_render_flush(struct fb_info *info);
-
-
- void bootsplash_free_file(struct splash_file_priv *fp);
-diff --git a/drivers/video/fbdev/core/bootsplash_render.c b/drivers/video/fbdev/core/bootsplash_render.c
-index 2ae36949d0e3..8c09c306ff67 100644
---- a/drivers/video/fbdev/core/bootsplash_render.c
-+++ b/drivers/video/fbdev/core/bootsplash_render.c
-@@ -186,3 +186,36 @@ void bootsplash_do_render_pictures(struct fb_info *info,
- pp->pic_header->width, pp->pic_header->height);
- }
- }
-+
-+
-+void bootsplash_do_render_flush(struct fb_info *info)
-+{
-+ /*
-+ * FB drivers using deferred_io (such as Xen) need to sync the
-+ * screen after modifying its contents. When the FB is mmap()ed
-+ * from userspace, this happens via a dirty pages callback, but
-+ * when modifying the FB from the kernel, there is no such thing.
-+ *
-+ * So let's issue a fake fb_copyarea (copying the FB onto itself)
-+ * to trick the FB driver into syncing the screen.
-+ *
-+ * A few DRM drivers' FB implementations are broken by not using
-+ * deferred_io when they really should - we match on the known
-+ * bad ones manually for now.
-+ */
-+ if (info->fbdefio
-+ || !strcmp(info->fix.id, "astdrmfb")
-+ || !strcmp(info->fix.id, "cirrusdrmfb")
-+ || !strcmp(info->fix.id, "mgadrmfb")) {
-+ struct fb_copyarea area;
-+
-+ area.dx = 0;
-+ area.dy = 0;
-+ area.width = info->var.xres;
-+ area.height = info->var.yres;
-+ area.sx = 0;
-+ area.sy = 0;
-+
-+ info->fbops->fb_copyarea(info, &area);
-+ }
-+}
diff --git a/sys-kernel/pinephone-pro-sources/files/0003-media-rockchip-rga-Fix-probe-bugs.patch b/sys-kernel/pinephone-pro-sources/files/0003-media-rockchip-rga-Fix-probe-bugs.patch
deleted file mode 100644
index a0e574f..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0003-media-rockchip-rga-Fix-probe-bugs.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 21 Nov 2021 17:00:09 +0100
-Subject: [PATCH 24/36] media: rockchip: rga: Fix probe bugs
-
-The check for dst_mmu_pages allocation failure was inverted.
-
-rga_parse_dt is missing a error return, so if some of the resources
-return DEFER_PROBE, probe will succeed without these resources.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/media/platform/rockchip/rga/rga.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
-index 4de5e8d..82cc0c0 100644
---- a/drivers/media/platform/rockchip/rga/rga.c
-+++ b/drivers/media/platform/rockchip/rga/rga.c
-@@ -815,8 +815,10 @@ static int rga_probe(struct platform_device *pdev)
- mutex_init(&rga->mutex);
-
- ret = rga_parse_dt(rga);
-- if (ret)
-+ if (ret) {
- dev_err(&pdev->dev, "Unable to parse OF data\n");
-+ return ret;
-+ }
-
- pm_runtime_enable(rga->dev);
-
-@@ -892,7 +894,7 @@ static int rga_probe(struct platform_device *pdev)
- }
- rga->dst_mmu_pages =
- (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3);
-- if (rga->dst_mmu_pages) {
-+ if (!rga->dst_mmu_pages) {
- ret = -ENOMEM;
- goto free_src_pages;
- }
diff --git a/sys-kernel/pinephone-pro-sources/files/0003-revert-fbcon-remove-no-op-fbcon_set_origin.patch b/sys-kernel/pinephone-pro-sources/files/0003-revert-fbcon-remove-no-op-fbcon_set_origin.patch
deleted file mode 100644
index 6491c54..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0003-revert-fbcon-remove-no-op-fbcon_set_origin.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- b/drivers/video/fbdev/core/fbcon.c
-+++ a/drivers/video/fbdev/core/fbcon.c
-@@ -163,6 +163,8 @@
-
- #define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
-
-+static int fbcon_set_origin(struct vc_data *);
-+
- static int fbcon_cursor_noblink;
-
- #define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
-@@ -2633,6 +2635,11 @@
- }
- }
-
-+static int fbcon_set_origin(struct vc_data *vc)
-+{
-+ return 0;
-+}
-+
- void fbcon_suspended(struct fb_info *info)
- {
- struct vc_data *vc = NULL;
-@@ -3103,6 +3110,7 @@
- .con_font_default = fbcon_set_def_font,
- .con_font_copy = fbcon_copy_font,
- .con_set_palette = fbcon_set_palette,
-+ .con_set_origin = fbcon_set_origin,
- .con_invert_region = fbcon_invert_region,
- .con_screen_pos = fbcon_screen_pos,
- .con_getxy = fbcon_getxy,
diff --git a/sys-kernel/pinephone-pro-sources/files/0004-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0004-bootsplash.patch
deleted file mode 100644
index 7eb54af..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0004-bootsplash.patch
+++ /dev/null
@@ -1,215 +0,0 @@
-diff --git a/drivers/video/fbdev/core/bootsplash_render.c b/drivers/video/fbdev/core/bootsplash_render.c
-index 8c09c306ff67..07e3a4eab811 100644
---- a/drivers/video/fbdev/core/bootsplash_render.c
-+++ b/drivers/video/fbdev/core/bootsplash_render.c
-@@ -155,6 +155,7 @@ void bootsplash_do_render_pictures(struct fb_info *info,
- for (i = 0; i < fp->header->num_pics; i++) {
- struct splash_blob_priv *bp;
- struct splash_pic_priv *pp = &fp->pics[i];
-+ const struct splash_pic_header *ph = pp->pic_header;
- long dst_xoff, dst_yoff;
-
- if (pp->blobs_loaded < 1)
-@@ -165,8 +166,139 @@ void bootsplash_do_render_pictures(struct fb_info *info,
- if (!bp || bp->blob_header->type != 0)
- continue;
-
-- dst_xoff = (info->var.xres - pp->pic_header->width) / 2;
-- dst_yoff = (info->var.yres - pp->pic_header->height) / 2;
-+ switch (ph->position) {
-+ case SPLASH_POS_FLAG_CORNER | SPLASH_CORNER_TOP_LEFT:
-+ dst_xoff = 0;
-+ dst_yoff = 0;
-+
-+ dst_xoff += ph->position_offset;
-+ dst_yoff += ph->position_offset;
-+ break;
-+ case SPLASH_POS_FLAG_CORNER | SPLASH_CORNER_TOP:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = 0;
-+
-+ dst_yoff += ph->position_offset;
-+ break;
-+ case SPLASH_POS_FLAG_CORNER | SPLASH_CORNER_TOP_RIGHT:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_yoff = 0;
-+
-+ dst_xoff -= ph->position_offset;
-+ dst_yoff += ph->position_offset;
-+ break;
-+ case SPLASH_POS_FLAG_CORNER | SPLASH_CORNER_RIGHT:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+
-+ dst_xoff -= ph->position_offset;
-+ break;
-+ case SPLASH_POS_FLAG_CORNER | SPLASH_CORNER_BOTTOM_RIGHT:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+
-+ dst_xoff -= ph->position_offset;
-+ dst_yoff -= ph->position_offset;
-+ break;
-+ case SPLASH_POS_FLAG_CORNER | SPLASH_CORNER_BOTTOM:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+
-+ dst_yoff -= ph->position_offset;
-+ break;
-+ case SPLASH_POS_FLAG_CORNER | SPLASH_CORNER_BOTTOM_LEFT:
-+ dst_xoff = 0 + ph->position_offset;
-+ dst_yoff = info->var.yres - pp->pic_header->height
-+ - ph->position_offset;
-+ break;
-+ case SPLASH_POS_FLAG_CORNER | SPLASH_CORNER_LEFT:
-+ dst_xoff = 0;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+
-+ dst_xoff += ph->position_offset;
-+ break;
-+
-+ case SPLASH_CORNER_TOP_LEFT:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+
-+ dst_xoff -= ph->position_offset;
-+ dst_yoff -= ph->position_offset;
-+ break;
-+ case SPLASH_CORNER_TOP:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+
-+ dst_yoff -= ph->position_offset;
-+ break;
-+ case SPLASH_CORNER_TOP_RIGHT:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+
-+ dst_xoff += ph->position_offset;
-+ dst_yoff -= ph->position_offset;
-+ break;
-+ case SPLASH_CORNER_RIGHT:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+
-+ dst_xoff += ph->position_offset;
-+ break;
-+ case SPLASH_CORNER_BOTTOM_RIGHT:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+
-+ dst_xoff += ph->position_offset;
-+ dst_yoff += ph->position_offset;
-+ break;
-+ case SPLASH_CORNER_BOTTOM:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+
-+ dst_yoff += ph->position_offset;
-+ break;
-+ case SPLASH_CORNER_BOTTOM_LEFT:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+
-+ dst_xoff -= ph->position_offset;
-+ dst_yoff += ph->position_offset;
-+ break;
-+ case SPLASH_CORNER_LEFT:
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+
-+ dst_xoff -= ph->position_offset;
-+ break;
-+
-+ default:
-+ /* As a fallback, center the picture. */
-+ dst_xoff = info->var.xres - pp->pic_header->width;
-+ dst_xoff /= 2;
-+ dst_yoff = info->var.yres - pp->pic_header->height;
-+ dst_yoff /= 2;
-+ break;
-+ }
-
- if (dst_xoff < 0
- || dst_yoff < 0
-diff --git a/include/uapi/linux/bootsplash_file.h b/include/uapi/linux/bootsplash_file.h
-index 89dc9cca8f0c..71cedcc68933 100644
---- a/include/uapi/linux/bootsplash_file.h
-+++ b/include/uapi/linux/bootsplash_file.h
-@@ -91,7 +91,32 @@ struct splash_pic_header {
- */
- uint8_t num_blobs;
-
-- uint8_t padding[27];
-+ /*
-+ * Corner to move the picture to / from.
-+ * 0x00 - Top left
-+ * 0x01 - Top
-+ * 0x02 - Top right
-+ * 0x03 - Right
-+ * 0x04 - Bottom right
-+ * 0x05 - Bottom
-+ * 0x06 - Bottom left
-+ * 0x07 - Left
-+ *
-+ * Flags:
-+ * 0x10 - Calculate offset from the corner towards the center,
-+ * rather than from the center towards the corner
-+ */
-+ uint8_t position;
-+
-+ /*
-+ * Pixel offset from the selected position.
-+ * Example: If the picture is in the top right corner, it will
-+ * be placed position_offset pixels from the top and
-+ * position_offset pixels from the right margin.
-+ */
-+ uint16_t position_offset;
-+
-+ uint8_t padding[24];
- } __attribute__((__packed__));
-
-
-@@ -115,4 +140,22 @@ struct splash_blob_header {
- uint8_t padding[9];
- } __attribute__((__packed__));
-
-+
-+
-+
-+/*
-+ * Enums for on-disk types
-+ */
-+enum splash_position {
-+ SPLASH_CORNER_TOP_LEFT = 0,
-+ SPLASH_CORNER_TOP = 1,
-+ SPLASH_CORNER_TOP_RIGHT = 2,
-+ SPLASH_CORNER_RIGHT = 3,
-+ SPLASH_CORNER_BOTTOM_RIGHT = 4,
-+ SPLASH_CORNER_BOTTOM = 5,
-+ SPLASH_CORNER_BOTTOM_LEFT = 6,
-+ SPLASH_CORNER_LEFT = 7,
-+ SPLASH_POS_FLAG_CORNER = 0x10,
-+};
-+
- #endif
diff --git a/sys-kernel/pinephone-pro-sources/files/0004-drm-dw-mipi-dsi-rockchip-Ensure-that-lane-is-properl.patch b/sys-kernel/pinephone-pro-sources/files/0004-drm-dw-mipi-dsi-rockchip-Ensure-that-lane-is-properl.patch
deleted file mode 100644
index 686dc3e..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0004-drm-dw-mipi-dsi-rockchip-Ensure-that-lane-is-properl.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From: =?utf-8?q?Kamil_Trzci=C5=84ski?=
-Date: Fri, 8 Jan 2021 00:19:23 +0100
-Subject: [PATCH 02/36] drm: dw-mipi-dsi-rockchip: Ensure that lane is
- properly configured
-MIME-Version: 1.0
-Content-Type: text/plain; charset="utf-8"
-Content-Transfer-Encoding: 8bit
-
-???
-
-Signed-of-by: Kamil Trzciński
----
- drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
-index a9acbcc..53c8b40 100644
---- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
-+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
-@@ -406,6 +406,14 @@ static int dw_mipi_dsi_phy_init(void *priv_data)
- */
- vco = (dsi->lane_mbps < 200) ? 0 : (dsi->lane_mbps + 100) / 200;
-
-+ if (dsi->cdata->lanecfg1_grf_reg) {
-+ regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg,
-+ dsi->cdata->lanecfg1);
-+
-+ dev_info(dsi->dev, "dw_mipi_dsi_phy_init / dw_mipi_dsi_rockchip_config: %08x => set=%08x\n",
-+ dsi->cdata->lanecfg1_grf_reg, dsi->cdata->lanecfg1);
-+ }
-+
- i = max_mbps_to_parameter(dsi->lane_mbps);
- if (i < 0) {
- DRM_DEV_ERROR(dsi->dev,
diff --git a/sys-kernel/pinephone-pro-sources/files/0004-revert-fbcon-remove-soft-scrollback-code.patch b/sys-kernel/pinephone-pro-sources/files/0004-revert-fbcon-remove-soft-scrollback-code.patch
deleted file mode 100644
index 4f97354..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0004-revert-fbcon-remove-soft-scrollback-code.patch
+++ /dev/null
@@ -1,500 +0,0 @@
---- b/drivers/video/fbdev/core/fbcon.c
-+++ a/drivers/video/fbdev/core/fbcon.c
-@@ -122,6 +122,12 @@
- /* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
- enums. */
- static int logo_shown = FBCON_LOGO_CANSHOW;
-+/* Software scrollback */
-+static int fbcon_softback_size = 32768;
-+static unsigned long softback_buf, softback_curr;
-+static unsigned long softback_in;
-+static unsigned long softback_top, softback_end;
-+static int softback_lines;
- /* console mappings */
- static int first_fb_vc;
- static int last_fb_vc = MAX_NR_CONSOLES - 1;
-@@ -161,6 +167,8 @@
-
- static const struct consw fb_con;
-
-+#define CM_SOFTBACK (8)
-+
- #define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
-
- static int fbcon_set_origin(struct vc_data *);
-@@ -365,6 +373,18 @@
- return color;
- }
-
-+static void fbcon_update_softback(struct vc_data *vc)
-+{
-+ int l = fbcon_softback_size / vc->vc_size_row;
-+
-+ if (l > 5)
-+ softback_end = softback_buf + l * vc->vc_size_row;
-+ else
-+ /* Smaller scrollback makes no sense, and 0 would screw
-+ the operation totally */
-+ softback_top = 0;
-+}
-+
- static void fb_flashcursor(struct work_struct *work)
- {
- struct fb_info *info = container_of(work, struct fb_info, queue);
-@@ -394,7 +414,7 @@
- c = scr_readw((u16 *) vc->vc_pos);
- mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
- CM_ERASE : CM_DRAW;
-+ ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1),
-- ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1),
- get_color(vc, info, c, 0));
- console_unlock();
- }
-@@ -451,7 +471,13 @@
- }
-
- if (!strncmp(options, "scrollback:", 11)) {
-+ options += 11;
-+ if (*options) {
-+ fbcon_softback_size = simple_strtoul(options, &options, 0);
-+ if (*options == 'k' || *options == 'K') {
-+ fbcon_softback_size *= 1024;
-+ }
-+ }
-- pr_warn("Ignoring scrollback size option\n");
- continue;
- }
-
-@@ -996,6 +1022,31 @@
-
- set_blitting_type(vc, info);
-
-+ if (info->fix.type != FB_TYPE_TEXT) {
-+ if (fbcon_softback_size) {
-+ if (!softback_buf) {
-+ softback_buf =
-+ (unsigned long)
-+ kvmalloc(fbcon_softback_size,
-+ GFP_KERNEL);
-+ if (!softback_buf) {
-+ fbcon_softback_size = 0;
-+ softback_top = 0;
-+ }
-+ }
-+ } else {
-+ if (softback_buf) {
-+ kvfree((void *) softback_buf);
-+ softback_buf = 0;
-+ softback_top = 0;
-+ }
-+ }
-+ if (softback_buf)
-+ softback_in = softback_top = softback_curr =
-+ softback_buf;
-+ softback_lines = 0;
-+ }
-+
- /* Setup default font */
- if (!p->fontdata && !vc->vc_font.data) {
- if (!fontname[0] || !(font = find_font(fontname)))
-@@ -1169,6 +1220,9 @@
- if (logo)
- fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
-
-+ if (vc == svc && softback_buf)
-+ fbcon_update_softback(vc);
-+
- if (ops->rotate_font && ops->rotate_font(info, vc)) {
- ops->rotate = FB_ROTATE_UR;
- set_blitting_type(vc, info);
-@@ -1331,6 +1385,7 @@
- {
- struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
- struct fbcon_ops *ops = info->fbcon_par;
-+ int y;
- int c = scr_readw((u16 *) vc->vc_pos);
-
- ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
-@@ -1334,11 +1389,19 @@ static void fbcon_cursor(struct vc_data
- fbcon_add_cursor_timer(info);
-
- ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
-+ if (mode & CM_SOFTBACK) {
-+ mode &= ~CM_SOFTBACK;
-+ y = softback_lines;
-+ } else {
-+ if (softback_lines)
-+ fbcon_set_origin(vc);
-+ y = 0;
-+ }
-
- if (!ops->cursor)
- return;
-
-- ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1),
-+ ops->cursor(vc, info, mode, y, get_color(vc, info, c, 1),
- get_color(vc, info, c, 0));
- }
-
-@@ -1416,6 +1479,8 @@
-
- if (con_is_visible(vc)) {
- update_screen(vc);
-+ if (softback_buf)
-+ fbcon_update_softback(vc);
- }
- }
-
-@@ -1553,6 +1618,99 @@
- scrollback_current = 0;
- }
-
-+static void fbcon_redraw_softback(struct vc_data *vc, struct fbcon_display *p,
-+ long delta)
-+{
-+ int count = vc->vc_rows;
-+ unsigned short *d, *s;
-+ unsigned long n;
-+ int line = 0;
-+
-+ d = (u16 *) softback_curr;
-+ if (d == (u16 *) softback_in)
-+ d = (u16 *) vc->vc_origin;
-+ n = softback_curr + delta * vc->vc_size_row;
-+ softback_lines -= delta;
-+ if (delta < 0) {
-+ if (softback_curr < softback_top && n < softback_buf) {
-+ n += softback_end - softback_buf;
-+ if (n < softback_top) {
-+ softback_lines -=
-+ (softback_top - n) / vc->vc_size_row;
-+ n = softback_top;
-+ }
-+ } else if (softback_curr >= softback_top
-+ && n < softback_top) {
-+ softback_lines -=
-+ (softback_top - n) / vc->vc_size_row;
-+ n = softback_top;
-+ }
-+ } else {
-+ if (softback_curr > softback_in && n >= softback_end) {
-+ n += softback_buf - softback_end;
-+ if (n > softback_in) {
-+ n = softback_in;
-+ softback_lines = 0;
-+ }
-+ } else if (softback_curr <= softback_in && n > softback_in) {
-+ n = softback_in;
-+ softback_lines = 0;
-+ }
-+ }
-+ if (n == softback_curr)
-+ return;
-+ softback_curr = n;
-+ s = (u16 *) softback_curr;
-+ if (s == (u16 *) softback_in)
-+ s = (u16 *) vc->vc_origin;
-+ while (count--) {
-+ unsigned short *start;
-+ unsigned short *le;
-+ unsigned short c;
-+ int x = 0;
-+ unsigned short attr = 1;
-+
-+ start = s;
-+ le = advance_row(s, 1);
-+ do {
-+ c = scr_readw(s);
-+ if (attr != (c & 0xff00)) {
-+ attr = c & 0xff00;
-+ if (s > start) {
-+ fbcon_putcs(vc, start, s - start,
-+ line, x);
-+ x += s - start;
-+ start = s;
-+ }
-+ }
-+ if (c == scr_readw(d)) {
-+ if (s > start) {
-+ fbcon_putcs(vc, start, s - start,
-+ line, x);
-+ x += s - start + 1;
-+ start = s + 1;
-+ } else {
-+ x++;
-+ start++;
-+ }
-+ }
-+ s++;
-+ d++;
-+ } while (s < le);
-+ if (s > start)
-+ fbcon_putcs(vc, start, s - start, line, x);
-+ line++;
-+ if (d == (u16 *) softback_end)
-+ d = (u16 *) softback_buf;
-+ if (d == (u16 *) softback_in)
-+ d = (u16 *) vc->vc_origin;
-+ if (s == (u16 *) softback_end)
-+ s = (u16 *) softback_buf;
-+ if (s == (u16 *) softback_in)
-+ s = (u16 *) vc->vc_origin;
-+ }
-+}
-+
- static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
- int line, int count, int dy)
- {
-@@ -1692,6 +1850,31 @@
- }
- }
-
-+static inline void fbcon_softback_note(struct vc_data *vc, int t,
-+ int count)
-+{
-+ unsigned short *p;
-+
-+ if (vc->vc_num != fg_console)
-+ return;
-+ p = (unsigned short *) (vc->vc_origin + t * vc->vc_size_row);
-+
-+ while (count) {
-+ scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row);
-+ count--;
-+ p = advance_row(p, 1);
-+ softback_in += vc->vc_size_row;
-+ if (softback_in == softback_end)
-+ softback_in = softback_buf;
-+ if (softback_in == softback_top) {
-+ softback_top += vc->vc_size_row;
-+ if (softback_top == softback_end)
-+ softback_top = softback_buf;
-+ }
-+ }
-+ softback_curr = softback_in;
-+}
-+
- static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
- enum con_scroll dir, unsigned int count)
- {
-@@ -1714,6 +1897,8 @@
- case SM_UP:
- if (count > vc->vc_rows) /* Maximum realistic size */
- count = vc->vc_rows;
-+ if (softback_top)
-+ fbcon_softback_note(vc, t, count);
- if (logo_shown >= 0)
- goto redraw_up;
- switch (p->scrollmode) {
-@@ -2084,6 +2269,14 @@
- info = registered_fb[con2fb_map[vc->vc_num]];
- ops = info->fbcon_par;
-
-+ if (softback_top) {
-+ if (softback_lines)
-+ fbcon_set_origin(vc);
-+ softback_top = softback_curr = softback_in = softback_buf;
-+ softback_lines = 0;
-+ fbcon_update_softback(vc);
-+ }
-+
- if (logo_shown >= 0) {
- struct vc_data *conp2 = vc_cons[logo_shown].d;
-
-@@ -2407,6 +2600,9 @@
- int cnt;
- char *old_data = NULL;
-
-+ if (con_is_visible(vc) && softback_lines)
-+ fbcon_set_origin(vc);
-+
- resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
- if (p->userfont)
- old_data = vc->vc_font.data;
-@@ -2432,6 +2628,8 @@
- cols /= w;
- rows /= h;
- vc_resize(vc, cols, rows);
-+ if (con_is_visible(vc) && softback_buf)
-+ fbcon_update_softback(vc);
- } else if (con_is_visible(vc)
- && vc->vc_mode == KD_TEXT) {
- fbcon_clear_margins(vc, 0);
-@@ -2590,7 +2788,19 @@
-
- static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
- {
-+ unsigned long p;
-+ int line;
-+
-+ if (vc->vc_num != fg_console || !softback_lines)
-+ return (u16 *) (vc->vc_origin + offset);
-+ line = offset / vc->vc_size_row;
-+ if (line >= softback_lines)
-+ return (u16 *) (vc->vc_origin + offset -
-+ softback_lines * vc->vc_size_row);
-+ p = softback_curr + offset;
-+ if (p >= softback_end)
-+ p += softback_buf - softback_end;
-+ return (u16 *) p;
-- return (u16 *) (vc->vc_origin + offset);
- }
-
- static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos,
-@@ -2604,7 +2814,22 @@
-
- x = offset % vc->vc_cols;
- y = offset / vc->vc_cols;
-+ if (vc->vc_num == fg_console)
-+ y += softback_lines;
- ret = pos + (vc->vc_cols - x) * 2;
-+ } else if (vc->vc_num == fg_console && softback_lines) {
-+ unsigned long offset = pos - softback_curr;
-+
-+ if (pos < softback_curr)
-+ offset += softback_end - softback_buf;
-+ offset /= 2;
-+ x = offset % vc->vc_cols;
-+ y = offset / vc->vc_cols;
-+ ret = pos + (vc->vc_cols - x) * 2;
-+ if (ret == softback_end)
-+ ret = softback_buf;
-+ if (ret == softback_in)
-+ ret = vc->vc_origin;
- } else {
- /* Should not happen */
- x = y = 0;
-@@ -2632,11 +2857,106 @@
- a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |
- (((a) & 0x0700) << 4);
- scr_writew(a, p++);
-+ if (p == (u16 *) softback_end)
-+ p = (u16 *) softback_buf;
-+ if (p == (u16 *) softback_in)
-+ p = (u16 *) vc->vc_origin;
-+ }
-+}
-+
-+static void fbcon_scrolldelta(struct vc_data *vc, int lines)
-+{
-+ struct fb_info *info = registered_fb[con2fb_map[fg_console]];
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ struct fbcon_display *disp = &fb_display[fg_console];
-+ int offset, limit, scrollback_old;
-+
-+ if (softback_top) {
-+ if (vc->vc_num != fg_console)
-+ return;
-+ if (vc->vc_mode != KD_TEXT || !lines)
-+ return;
-+ if (logo_shown >= 0) {
-+ struct vc_data *conp2 = vc_cons[logo_shown].d;
-+
-+ if (conp2->vc_top == logo_lines
-+ && conp2->vc_bottom == conp2->vc_rows)
-+ conp2->vc_top = 0;
-+ if (logo_shown == vc->vc_num) {
-+ unsigned long p, q;
-+ int i;
-+
-+ p = softback_in;
-+ q = vc->vc_origin +
-+ logo_lines * vc->vc_size_row;
-+ for (i = 0; i < logo_lines; i++) {
-+ if (p == softback_top)
-+ break;
-+ if (p == softback_buf)
-+ p = softback_end;
-+ p -= vc->vc_size_row;
-+ q -= vc->vc_size_row;
-+ scr_memcpyw((u16 *) q, (u16 *) p,
-+ vc->vc_size_row);
-+ }
-+ softback_in = softback_curr = p;
-+ update_region(vc, vc->vc_origin,
-+ logo_lines * vc->vc_cols);
-+ }
-+ logo_shown = FBCON_LOGO_CANSHOW;
-+ }
-+ fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
-+ fbcon_redraw_softback(vc, disp, lines);
-+ fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK);
-+ return;
- }
-+
-+ if (!scrollback_phys_max)
-+ return;
-+
-+ scrollback_old = scrollback_current;
-+ scrollback_current -= lines;
-+ if (scrollback_current < 0)
-+ scrollback_current = 0;
-+ else if (scrollback_current > scrollback_max)
-+ scrollback_current = scrollback_max;
-+ if (scrollback_current == scrollback_old)
-+ return;
-+
-+ if (fbcon_is_inactive(vc, info))
-+ return;
-+
-+ fbcon_cursor(vc, CM_ERASE);
-+
-+ offset = disp->yscroll - scrollback_current;
-+ limit = disp->vrows;
-+ switch (disp->scrollmode) {
-+ case SCROLL_WRAP_MOVE:
-+ info->var.vmode |= FB_VMODE_YWRAP;
-+ break;
-+ case SCROLL_PAN_MOVE:
-+ case SCROLL_PAN_REDRAW:
-+ limit -= vc->vc_rows;
-+ info->var.vmode &= ~FB_VMODE_YWRAP;
-+ break;
-+ }
-+ if (offset < 0)
-+ offset += limit;
-+ else if (offset >= limit)
-+ offset -= limit;
-+
-+ ops->var.xoffset = 0;
-+ ops->var.yoffset = offset * vc->vc_font.height;
-+ ops->update_start(info);
-+
-+ if (!scrollback_current)
-+ fbcon_cursor(vc, CM_DRAW);
- }
-
- static int fbcon_set_origin(struct vc_data *vc)
- {
-+ if (softback_lines)
-+ fbcon_scrolldelta(vc, softback_lines);
- return 0;
- }
-
-@@ -2700,6 +3020,8 @@
-
- fbcon_set_palette(vc, color_table);
- update_screen(vc);
-+ if (softback_buf)
-+ fbcon_update_softback(vc);
- }
- }
-
-@@ -3110,6 +3432,7 @@
- .con_font_default = fbcon_set_def_font,
- .con_font_copy = fbcon_copy_font,
- .con_set_palette = fbcon_set_palette,
-+ .con_scrolldelta = fbcon_scrolldelta,
- .con_set_origin = fbcon_set_origin,
- .con_invert_region = fbcon_invert_region,
- .con_screen_pos = fbcon_screen_pos,
-@@ -3344,6 +3667,9 @@
- }
- #endif
-
-+ kvfree((void *)softback_buf);
-+ softback_buf = 0UL;
-+
- for_each_registered_fb(i) {
- int pending = 0;
-
diff --git a/sys-kernel/pinephone-pro-sources/files/0005-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0005-bootsplash.patch
deleted file mode 100644
index 2785c5e..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0005-bootsplash.patch
+++ /dev/null
@@ -1,327 +0,0 @@
-diff --git a/drivers/video/fbdev/core/bootsplash.c b/drivers/video/fbdev/core/bootsplash.c
-index 815b007f81ca..c8642142cfea 100644
---- a/drivers/video/fbdev/core/bootsplash.c
-+++ b/drivers/video/fbdev/core/bootsplash.c
-@@ -53,6 +53,14 @@ static void splash_callback_redraw_vc(struct work_struct *ignored)
- console_unlock();
- }
-
-+static void splash_callback_animation(struct work_struct *ignored)
-+{
-+ if (bootsplash_would_render_now()) {
-+ /* This will also re-schedule this delayed worker */
-+ splash_callback_redraw_vc(ignored);
-+ }
-+}
-+
-
- static bool is_fb_compatible(const struct fb_info *info)
- {
-@@ -103,17 +111,44 @@ static bool is_fb_compatible(const struct fb_info *info)
- */
- void bootsplash_render_full(struct fb_info *info)
- {
-+ bool is_update = false;
-+
- mutex_lock(&splash_state.data_lock);
-
-- if (!is_fb_compatible(info))
-- goto out;
-+ /*
-+ * If we've painted on this FB recently, we don't have to do
-+ * the sanity checks and background drawing again.
-+ */
-+ if (splash_state.splash_fb == info)
-+ is_update = true;
-+
-+
-+ if (!is_update) {
-+ /* Check whether we actually support this FB. */
-+ splash_state.splash_fb = NULL;
-+
-+ if (!is_fb_compatible(info))
-+ goto out;
-+
-+ /* Draw the background only once */
-+ bootsplash_do_render_background(info, splash_state.file);
-
-- bootsplash_do_render_background(info, splash_state.file);
-+ /* Mark this FB as last seen */
-+ splash_state.splash_fb = info;
-+ }
-
-- bootsplash_do_render_pictures(info, splash_state.file);
-+ bootsplash_do_render_pictures(info, splash_state.file, is_update);
-
- bootsplash_do_render_flush(info);
-
-+ bootsplash_do_step_animations(splash_state.file);
-+
-+ /* Schedule update for animated splash screens */
-+ if (splash_state.file->frame_ms > 0)
-+ schedule_delayed_work(&splash_state.dwork_animation,
-+ msecs_to_jiffies(
-+ splash_state.file->frame_ms));
-+
- out:
- mutex_unlock(&splash_state.data_lock);
- }
-@@ -169,8 +204,14 @@ void bootsplash_enable(void)
-
- was_enabled = test_and_set_bit(0, &splash_state.enabled);
-
-- if (!was_enabled)
-+ if (!was_enabled) {
-+ /* Force a full redraw when the splash is re-activated */
-+ mutex_lock(&splash_state.data_lock);
-+ splash_state.splash_fb = NULL;
-+ mutex_unlock(&splash_state.data_lock);
-+
- schedule_work(&splash_state.work_redraw_vc);
-+ }
- }
-
-
-@@ -227,6 +268,14 @@ ATTRIBUTE_GROUPS(splash_dev);
- */
- static int splash_resume(struct device *device)
- {
-+ /*
-+ * Force full redraw on resume since we've probably lost the
-+ * framebuffer's contents meanwhile
-+ */
-+ mutex_lock(&splash_state.data_lock);
-+ splash_state.splash_fb = NULL;
-+ mutex_unlock(&splash_state.data_lock);
-+
- if (bootsplash_would_render_now())
- schedule_work(&splash_state.work_redraw_vc);
-
-@@ -235,6 +284,7 @@ static int splash_resume(struct device *device)
-
- static int splash_suspend(struct device *device)
- {
-+ cancel_delayed_work_sync(&splash_state.dwork_animation);
- cancel_work_sync(&splash_state.work_redraw_vc);
-
- return 0;
-@@ -296,6 +346,8 @@ void bootsplash_init(void)
- set_bit(0, &splash_state.enabled);
-
- INIT_WORK(&splash_state.work_redraw_vc, splash_callback_redraw_vc);
-+ INIT_DELAYED_WORK(&splash_state.dwork_animation,
-+ splash_callback_animation);
-
-
- if (!splash_state.bootfile || !strlen(splash_state.bootfile))
-diff --git a/drivers/video/fbdev/core/bootsplash_internal.h b/drivers/video/fbdev/core/bootsplash_internal.h
-index 0acb383aa4e3..b3a74835d90f 100644
---- a/drivers/video/fbdev/core/bootsplash_internal.h
-+++ b/drivers/video/fbdev/core/bootsplash_internal.h
-@@ -37,6 +37,8 @@ struct splash_pic_priv {
-
- struct splash_blob_priv *blobs;
- u16 blobs_loaded;
-+
-+ u16 anim_nextframe;
- };
-
-
-@@ -45,6 +47,12 @@ struct splash_file_priv {
- const struct splash_file_header *header;
-
- struct splash_pic_priv *pics;
-+
-+ /*
-+ * A local copy of the frame delay in the header.
-+ * We modify it to keep the code simple.
-+ */
-+ u16 frame_ms;
- };
-
-
-@@ -71,6 +79,7 @@ struct splash_priv {
- struct platform_device *splash_device;
-
- struct work_struct work_redraw_vc;
-+ struct delayed_work dwork_animation;
-
- /* Splash data structures including lock for everything below */
- struct mutex data_lock;
-@@ -88,8 +97,10 @@ struct splash_priv {
- void bootsplash_do_render_background(struct fb_info *info,
- const struct splash_file_priv *fp);
- void bootsplash_do_render_pictures(struct fb_info *info,
-- const struct splash_file_priv *fp);
-+ const struct splash_file_priv *fp,
-+ bool is_update);
- void bootsplash_do_render_flush(struct fb_info *info);
-+void bootsplash_do_step_animations(struct splash_file_priv *fp);
-
-
- void bootsplash_free_file(struct splash_file_priv *fp);
-diff --git a/drivers/video/fbdev/core/bootsplash_load.c b/drivers/video/fbdev/core/bootsplash_load.c
-index fd807571ab7d..1f661b2d4cc9 100644
---- a/drivers/video/fbdev/core/bootsplash_load.c
-+++ b/drivers/video/fbdev/core/bootsplash_load.c
-@@ -71,6 +71,7 @@ struct splash_file_priv *bootsplash_load_firmware(struct device *device,
- {
- const struct firmware *fw;
- struct splash_file_priv *fp;
-+ bool have_anim = false;
- unsigned int i;
- const u8 *walker;
-
-@@ -135,6 +136,13 @@ struct splash_file_priv *bootsplash_load_firmware(struct device *device,
- goto err;
- }
-
-+ if (ph->anim_type > SPLASH_ANIM_LOOP_FORWARD) {
-+ pr_warn("Picture %u: Unsupported animation type %u.\n",
-+ i, ph->anim_type);
-+
-+ ph->anim_type = SPLASH_ANIM_NONE;
-+ }
-+
- pp->pic_header = ph;
- pp->blobs = vzalloc(ph->num_blobs
- * sizeof(struct splash_blob_priv));
-@@ -202,6 +210,7 @@ struct splash_file_priv *bootsplash_load_firmware(struct device *device,
- /* Walk over pictures and ensure all blob slots are filled */
- for (i = 0; i < fp->header->num_pics; i++) {
- struct splash_pic_priv *pp = &fp->pics[i];
-+ const struct splash_pic_header *ph = pp->pic_header;
-
- if (pp->blobs_loaded != pp->pic_header->num_blobs) {
- pr_err("Picture %u doesn't have all blob slots filled.\n",
-@@ -209,8 +218,20 @@ struct splash_file_priv *bootsplash_load_firmware(struct device *device,
-
- goto err;
- }
-+
-+ if (ph->anim_type
-+ && ph->num_blobs > 1
-+ && ph->anim_loop < pp->blobs_loaded)
-+ have_anim = true;
- }
-
-+ if (!have_anim)
-+ /* Disable animation timer if there is nothing to animate */
-+ fp->frame_ms = 0;
-+ else
-+ /* Enforce minimum delay between frames */
-+ fp->frame_ms = max((u16)20, fp->header->frame_ms);
-+
- pr_info("Loaded (%ld bytes, %u pics, %u blobs).\n",
- fw->size,
- fp->header->num_pics,
-diff --git a/drivers/video/fbdev/core/bootsplash_render.c b/drivers/video/fbdev/core/bootsplash_render.c
-index 07e3a4eab811..76033606ca8a 100644
---- a/drivers/video/fbdev/core/bootsplash_render.c
-+++ b/drivers/video/fbdev/core/bootsplash_render.c
-@@ -148,7 +148,8 @@ void bootsplash_do_render_background(struct fb_info *info,
-
-
- void bootsplash_do_render_pictures(struct fb_info *info,
-- const struct splash_file_priv *fp)
-+ const struct splash_file_priv *fp,
-+ bool is_update)
- {
- unsigned int i;
-
-@@ -161,7 +162,11 @@ void bootsplash_do_render_pictures(struct fb_info *info,
- if (pp->blobs_loaded < 1)
- continue;
-
-- bp = &pp->blobs[0];
-+ /* Skip static pictures when refreshing animations */
-+ if (ph->anim_type == SPLASH_ANIM_NONE && is_update)
-+ continue;
-+
-+ bp = &pp->blobs[pp->anim_nextframe];
-
- if (!bp || bp->blob_header->type != 0)
- continue;
-@@ -351,3 +356,24 @@ void bootsplash_do_render_flush(struct fb_info *info)
- info->fbops->fb_copyarea(info, &area);
- }
- }
-+
-+
-+void bootsplash_do_step_animations(struct splash_file_priv *fp)
-+{
-+ unsigned int i;
-+
-+ /* Step every animation once */
-+ for (i = 0; i < fp->header->num_pics; i++) {
-+ struct splash_pic_priv *pp = &fp->pics[i];
-+
-+ if (pp->blobs_loaded < 2
-+ || pp->pic_header->anim_loop > pp->blobs_loaded)
-+ continue;
-+
-+ if (pp->pic_header->anim_type == SPLASH_ANIM_LOOP_FORWARD) {
-+ pp->anim_nextframe++;
-+ if (pp->anim_nextframe >= pp->pic_header->num_blobs)
-+ pp->anim_nextframe = pp->pic_header->anim_loop;
-+ }
-+ }
-+}
-diff --git a/include/uapi/linux/bootsplash_file.h b/include/uapi/linux/bootsplash_file.h
-index 71cedcc68933..b3af0a3c6487 100644
---- a/include/uapi/linux/bootsplash_file.h
-+++ b/include/uapi/linux/bootsplash_file.h
-@@ -77,7 +77,17 @@ struct splash_file_header {
- uint16_t num_blobs;
- uint8_t num_pics;
-
-- uint8_t padding[103];
-+ uint8_t unused_1;
-+
-+ /*
-+ * Milliseconds to wait before painting the next frame in
-+ * an animation.
-+ * This is actually a minimum, as the system is allowed to
-+ * stall for longer between frames.
-+ */
-+ uint16_t frame_ms;
-+
-+ uint8_t padding[100];
- } __attribute__((__packed__));
-
-
-@@ -116,7 +126,23 @@ struct splash_pic_header {
- */
- uint16_t position_offset;
-
-- uint8_t padding[24];
-+ /*
-+ * Animation type.
-+ * 0 - off
-+ * 1 - forward loop
-+ */
-+ uint8_t anim_type;
-+
-+ /*
-+ * Animation loop point.
-+ * Actual meaning depends on animation type:
-+ * Type 0 - Unused
-+ * 1 - Frame at which to restart the forward loop
-+ * (allowing for "intro" frames)
-+ */
-+ uint8_t anim_loop;
-+
-+ uint8_t padding[22];
- } __attribute__((__packed__));
-
-
-@@ -158,4 +184,9 @@ enum splash_position {
- SPLASH_POS_FLAG_CORNER = 0x10,
- };
-
-+enum splash_anim_type {
-+ SPLASH_ANIM_NONE = 0,
-+ SPLASH_ANIM_LOOP_FORWARD = 1,
-+};
-+
- #endif
diff --git a/sys-kernel/pinephone-pro-sources/files/0005-drm-rockchip-dw-mipi-dsi-Fix-missing-clk_disable_unp.patch b/sys-kernel/pinephone-pro-sources/files/0005-drm-rockchip-dw-mipi-dsi-Fix-missing-clk_disable_unp.patch
deleted file mode 100644
index 425c986..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0005-drm-rockchip-dw-mipi-dsi-Fix-missing-clk_disable_unp.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 17 Oct 2021 18:04:21 +0200
-Subject: [PATCH 03/36] drm: rockchip: dw-mipi-dsi: Fix missing
- clk_disable_unprepare for pllref_clk
-
-In some error paths, clk_disable_unprepare function was not called.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 10 +++++++---
- 1 file changed, 7 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
-index 53c8b40..095d0f1 100644
---- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
-+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
-@@ -960,7 +960,7 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
- ret = clk_prepare_enable(dsi->grf_clk);
- if (ret) {
- DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
-- return ret;
-+ goto err_pllref_disable;
- }
-
- dw_mipi_dsi_rockchip_config(dsi);
-@@ -972,16 +972,20 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
- ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev);
- if (ret) {
- DRM_DEV_ERROR(dev, "Failed to create drm encoder\n");
-- return ret;
-+ goto err_pllref_disable;
- }
-
- ret = dw_mipi_dsi_bind(dsi->dmd, &dsi->encoder);
- if (ret) {
- DRM_DEV_ERROR(dev, "Failed to bind: %d\n", ret);
-- return ret;
-+ goto err_pllref_disable;
- }
-
- return 0;
-+
-+err_pllref_disable:
-+ clk_disable_unprepare(dsi->pllref_clk);
-+ return ret;
- }
-
- static void dw_mipi_dsi_rockchip_unbind(struct device *dev,
diff --git a/sys-kernel/pinephone-pro-sources/files/0006-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0006-bootsplash.patch
deleted file mode 100644
index d6c6db6..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0006-bootsplash.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
-index 2ebaba16f785..416735ab6dc1 100644
---- a/drivers/tty/vt/vt.c
-+++ b/drivers/tty/vt/vt.c
-@@ -105,6 +105,7 @@
- #include
- #include
- #include
-+#include
-
- #define MAX_NR_CON_DRIVER 16
-
-@@ -4235,6 +4236,7 @@ void do_unblank_screen(int leaving_gfx)
- }
-
- console_blanked = 0;
-+ bootsplash_mark_dirty();
- if (vc->vc_sw->con_blank(vc, 0, leaving_gfx))
- /* Low-level driver cannot restore -> do it ourselves */
- update_screen(vc);
-diff --git a/drivers/video/fbdev/core/bootsplash.c b/drivers/video/fbdev/core/bootsplash.c
-index c8642142cfea..13fcaabbc2ca 100644
---- a/drivers/video/fbdev/core/bootsplash.c
-+++ b/drivers/video/fbdev/core/bootsplash.c
-@@ -165,6 +165,13 @@ bool bootsplash_would_render_now(void)
- && bootsplash_is_enabled();
- }
-
-+void bootsplash_mark_dirty(void)
-+{
-+ mutex_lock(&splash_state.data_lock);
-+ splash_state.splash_fb = NULL;
-+ mutex_unlock(&splash_state.data_lock);
-+}
-+
- bool bootsplash_is_enabled(void)
- {
- bool was_enabled;
-@@ -206,9 +213,7 @@ void bootsplash_enable(void)
-
- if (!was_enabled) {
- /* Force a full redraw when the splash is re-activated */
-- mutex_lock(&splash_state.data_lock);
-- splash_state.splash_fb = NULL;
-- mutex_unlock(&splash_state.data_lock);
-+ bootsplash_mark_dirty();
-
- schedule_work(&splash_state.work_redraw_vc);
- }
-@@ -272,9 +277,7 @@ static int splash_resume(struct device *device)
- * Force full redraw on resume since we've probably lost the
- * framebuffer's contents meanwhile
- */
-- mutex_lock(&splash_state.data_lock);
-- splash_state.splash_fb = NULL;
-- mutex_unlock(&splash_state.data_lock);
-+ bootsplash_mark_dirty();
-
- if (bootsplash_would_render_now())
- schedule_work(&splash_state.work_redraw_vc);
-diff --git a/include/linux/bootsplash.h b/include/linux/bootsplash.h
-index c6dd0b43180d..4075098aaadd 100644
---- a/include/linux/bootsplash.h
-+++ b/include/linux/bootsplash.h
-@@ -19,6 +19,8 @@ extern void bootsplash_render_full(struct fb_info *info);
-
- extern bool bootsplash_would_render_now(void);
-
-+extern void bootsplash_mark_dirty(void);
-+
- extern bool bootsplash_is_enabled(void);
- extern void bootsplash_disable(void);
- extern void bootsplash_enable(void);
-@@ -31,6 +33,8 @@ extern void bootsplash_init(void);
-
- #define bootsplash_would_render_now() (false)
-
-+#define bootsplash_mark_dirty()
-+
- #define bootsplash_is_enabled() (false)
- #define bootsplash_disable()
- #define bootsplash_enable()
diff --git a/sys-kernel/pinephone-pro-sources/files/0006-drm-bridge-dw-mipi-dsi-Fix-enable-disable-of-dsi-con.patch b/sys-kernel/pinephone-pro-sources/files/0006-drm-bridge-dw-mipi-dsi-Fix-enable-disable-of-dsi-con.patch
deleted file mode 100644
index e2eddd2..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0006-drm-bridge-dw-mipi-dsi-Fix-enable-disable-of-dsi-con.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 17 Oct 2021 20:14:25 +0200
-Subject: [PATCH 04/36] drm: bridge: dw-mipi-dsi: Fix enable/disable of dsi
- controller
-
-The driver had it all wrong. mode_set is not for enabling the
-DSI controller, that should be done in pre_enable so that
-panel driver can initialize the panel (working dsi controller
-is needed for that). Having dsi powerup in mode_set led to
-all kind of fun, because disable would be called more often
-than mode_set.
-
-The whole panel/dsi enable/disable dance is such (for future
-reference):
-
-- dsi: mode set
-- panel: prepare (we turn on panel power)
-- dsi: pre enable (we enable and setup DSI)
-- dsi: enable (we enable video data)
-- panel: enable (we configure and turn on the display)
-
-For disable:
-
-- panel: disable (we turn off the display nicely)
-- dsi: disable (we disable DSI)
-- dsi: post disable
-- panel: unprepare (we power off display power, panel should
- be safely sleeping now)
-
-Signed-off-by: Ondrej Jirman
----
- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 45 +++++++++++++++++++--------
- 1 file changed, 32 insertions(+), 13 deletions(-)
-
-diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
-index e44e18a..9cce2ab 100644
---- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
-+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
-@@ -266,6 +266,7 @@ struct dw_mipi_dsi {
- struct dw_mipi_dsi *master; /* dual-dsi master ptr */
- struct dw_mipi_dsi *slave; /* dual-dsi slave ptr */
-
-+ struct drm_display_mode mode;
- const struct dw_mipi_dsi_plat_data *plat_data;
- };
-
-@@ -597,6 +598,8 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
- {
- u32 val;
-
-+ dev_info(dsi->dev, "mode %d\n", (int)mode_flags);
-+
- dsi_write(dsi, DSI_PWR_UP, RESET);
-
- if (mode_flags & MIPI_DSI_MODE_VIDEO) {
-@@ -871,11 +874,20 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
- dsi_write(dsi, DSI_INT_MSK1, 0);
- }
-
-+static void dw_mipi_dsi_bridge_disable(struct drm_bridge *bridge)
-+{
-+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
-+
-+ dev_info(dsi->dev, "disable\n");
-+}
-+
- static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
- {
- struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
- const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
-
-+ dev_info(dsi->dev, "post disable\n");
-+
- /*
- * Switch to command mode before panel-bridge post_disable &
- * panel unprepare.
-@@ -884,15 +896,6 @@ static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
- */
- dw_mipi_dsi_set_mode(dsi, 0);
-
-- /*
-- * TODO Only way found to call panel-bridge post_disable &
-- * panel unprepare before the dsi "final" disable...
-- * This needs to be fixed in the drm_bridge framework and the API
-- * needs to be updated to manage our own call chains...
-- */
-- if (dsi->panel_bridge->funcs->post_disable)
-- dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
--
- if (phy_ops->power_off)
- phy_ops->power_off(dsi->plat_data->priv_data);
-
-@@ -921,7 +924,7 @@ static unsigned int dw_mipi_dsi_get_lanes(struct dw_mipi_dsi *dsi)
- return dsi->lanes;
- }
-
--static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi,
-+static void dw_mipi_dsi_enable(struct dw_mipi_dsi *dsi,
- const struct drm_display_mode *adjusted_mode)
- {
- const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
-@@ -973,16 +976,30 @@ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
- {
- struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
-
-- dw_mipi_dsi_mode_set(dsi, adjusted_mode);
-+ dev_info(dsi->dev, "mode set\n");
-+
-+ /* Store the display mode for plugin/DKMS poweron events */
-+ memcpy(&dsi->mode, mode, sizeof(dsi->mode));
-+}
-+
-+static void dw_mipi_dsi_bridge_pre_enable(struct drm_bridge *bridge)
-+{
-+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
-+
-+ dev_info(dsi->dev, "pre enable\n");
-+
-+ /* power up the dsi ctl into a command mode */
-+ dw_mipi_dsi_enable(dsi, &dsi->mode);
- if (dsi->slave)
-- dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode);
-+ dw_mipi_dsi_enable(dsi->slave, &dsi->mode);
- }
-
- static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
- {
- struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
-
-- /* Switch to video mode for panel-bridge enable & panel enable */
-+ dev_info(dsi->dev, "enable\n");
-+
- dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO);
- if (dsi->slave)
- dw_mipi_dsi_set_mode(dsi->slave, MIPI_DSI_MODE_VIDEO);
-@@ -1033,7 +1050,9 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge,
-
- static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
- .mode_set = dw_mipi_dsi_bridge_mode_set,
-+ .pre_enable = dw_mipi_dsi_bridge_pre_enable,
- .enable = dw_mipi_dsi_bridge_enable,
-+ .disable = dw_mipi_dsi_bridge_disable,
- .post_disable = dw_mipi_dsi_bridge_post_disable,
- .mode_valid = dw_mipi_dsi_bridge_mode_valid,
- .attach = dw_mipi_dsi_bridge_attach,
diff --git a/sys-kernel/pinephone-pro-sources/files/0007-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0007-bootsplash.patch
deleted file mode 100644
index 3f82eb0..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0007-bootsplash.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
-index f4166263bb3a..a248429194bb 100644
---- a/drivers/tty/vt/keyboard.c
-+++ b/drivers/tty/vt/keyboard.c
-@@ -49,6 +49,8 @@
-
- #include
-
-+#include
-+
- /*
- * Exported functions/variables
- */
-@@ -1413,6 +1415,28 @@ static void kbd_keycode(unsigned int key
- }
- #endif
-
-+ /* Trap keys when bootsplash is shown */
-+ if (bootsplash_would_render_now()) {
-+ /* Deactivate bootsplash on ESC or Alt+Fxx VT switch */
-+ if (keycode >= KEY_F1 && keycode <= KEY_F12) {
-+ bootsplash_disable();
-+
-+ /*
-+ * No return here since we want to actually
-+ * perform the VT switch.
-+ */
-+ } else {
-+ if (keycode == KEY_ESC)
-+ bootsplash_disable();
-+
-+ /*
-+ * Just drop any other keys.
-+ * Their effect would be hidden by the splash.
-+ */
-+ return;
-+ }
-+ }
-+
- if (kbd->kbdmode == VC_MEDIUMRAW) {
- /*
- * This is extended medium raw mode, with keys above 127
diff --git a/sys-kernel/pinephone-pro-sources/files/0007-drm-dw-mipi-dsi-rockchip-Never-allow-lane-bandwidth-.patch b/sys-kernel/pinephone-pro-sources/files/0007-drm-dw-mipi-dsi-rockchip-Never-allow-lane-bandwidth-.patch
deleted file mode 100644
index 003fd7c..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0007-drm-dw-mipi-dsi-rockchip-Never-allow-lane-bandwidth-.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Ondrej Jirman
-Date: Tue, 16 Nov 2021 21:16:26 +0100
-Subject: [PATCH 07/36] drm: dw-mipi-dsi-rockchip: Never allow lane bandwidth
- to be less than requested
-
-Bandwidth can be less than requested in some cases, because the search
-for best values only checked for absolute difference from ideal value.
-
-This is likely not intentional.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
-index 095d0f1..bd488a8 100644
---- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
-+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
-@@ -612,7 +612,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
- continue;
-
- delta = abs(fout - tmp);
-- if (delta < min_delta) {
-+ if (delta < min_delta && fout < tmp) {
- best_prediv = _prediv;
- best_fbdiv = _fbdiv;
- min_delta = delta;
diff --git a/sys-kernel/pinephone-pro-sources/files/0008-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0008-bootsplash.patch
deleted file mode 100644
index 8a3b715..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0008-bootsplash.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
-index 3ffc1ce29023..bc6a24c9dfa8 100644
---- a/drivers/tty/sysrq.c
-+++ b/drivers/tty/sysrq.c
-@@ -49,6 +49,7 @@
- #include
- #include
- #include
-+#include
-
- #include
- #include
-@@ -104,6 +105,8 @@ static void sysrq_handle_SAK(int key)
- {
- struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
- schedule_work(SAK_work);
-+
-+ bootsplash_disable();
- }
- static struct sysrq_key_op sysrq_SAK_op = {
- .handler = sysrq_handle_SAK,
diff --git a/sys-kernel/pinephone-pro-sources/files/0008-drm-rockchip-cdn-dp-Disable-CDN-DP-on-disconnect.patch b/sys-kernel/pinephone-pro-sources/files/0008-drm-rockchip-cdn-dp-Disable-CDN-DP-on-disconnect.patch
deleted file mode 100644
index 187e5e2..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0008-drm-rockchip-cdn-dp-Disable-CDN-DP-on-disconnect.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From: Ondrej Jirman
-Date: Sat, 20 Nov 2021 14:35:52 +0100
-Subject: [PATCH 09/36] drm: rockchip: cdn-dp: Disable CDN DP on disconnect
-
-Why not?
-
-Signed-off-by: Ondrej Jirman
----
- drivers/gpu/drm/rockchip/cdn-dp-core.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
-index 16497c3..f4dcd9e 100644
---- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
-+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
-@@ -934,6 +934,7 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
- DRM_DEV_INFO(dp->dev, "Not connected. Disabling cdn\n");
- dp->connected = false;
-
-+ cdn_dp_disable(dp);
- /* Connected but not enabled, enable the block */
- } else if (!dp->active) {
- DRM_DEV_INFO(dp->dev, "Connected, not enabled. Enabling cdn\n");
diff --git a/sys-kernel/pinephone-pro-sources/files/0009-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0009-bootsplash.patch
deleted file mode 100644
index add68e7..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0009-bootsplash.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
-index 9a39a6fcfe98..8a9c67e1c5d8 100644
---- a/drivers/video/fbdev/core/fbcon.c
-+++ b/drivers/video/fbdev/core/fbcon.c
-@@ -1343,6 +1343,16 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
- int y;
- int c = scr_readw((u16 *) vc->vc_pos);
-
-+ /*
-+ * Disable the splash here so we don't have to hook into
-+ * vt_console_print() in drivers/tty/vt/vt.c
-+ *
-+ * We'd disable the splash just before the call to
-+ * hide_cursor() anyway, so this spot is just fine.
-+ */
-+ if (oops_in_progress)
-+ bootsplash_disable();
-+
- ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
-
- if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
diff --git a/sys-kernel/pinephone-pro-sources/files/0009-video-fbdev-Add-events-for-early-fb-event-support.patch b/sys-kernel/pinephone-pro-sources/files/0009-video-fbdev-Add-events-for-early-fb-event-support.patch
deleted file mode 100644
index 4ceaad0..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0009-video-fbdev-Add-events-for-early-fb-event-support.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 17 Oct 2021 12:46:01 +0200
-Subject: [PATCH 10/36] video: fbdev: Add events for early fb event support
-
-This patch adds FB_EARLY_EVENT_BLANK and FB_R_EARLY_EVENT_BLANK
-event mode supports. first, fb_notifier_call_chain() is called with
-FB_EARLY_EVENT_BLANK and fb_blank() of specific fb driver is called
-and then fb_notifier_call_chain() is called with FB_EVENT_BLANK again
-at fb_blank(). and if fb_blank() was failed then fb_nitifier_call_chain()
-would be called with FB_R_EARLY_EVENT_BLANK to revert the previous effects.
-
-Signed-off-by: Inki Dae
-Signed-off-by: Kyungmin Park
----
- drivers/video/fbdev/core/fbmem.c | 12 +++++++++++-
- include/linux/fb.h | 5 +++++
- 2 files changed, 16 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
-index 0fa7ede..71d9d4a 100644
---- a/drivers/video/fbdev/core/fbmem.c
-+++ b/drivers/video/fbdev/core/fbmem.c
-@@ -1067,7 +1067,7 @@ int
- fb_blank(struct fb_info *info, int blank)
- {
- struct fb_event event;
-- int ret = -EINVAL;
-+ int ret = -EINVAL, early_ret;
-
- if (blank > FB_BLANK_POWERDOWN)
- blank = FB_BLANK_POWERDOWN;
-@@ -1075,11 +1075,21 @@ fb_blank(struct fb_info *info, int blank)
- event.info = info;
- event.data = ␣
-
-+ early_ret = fb_notifier_call_chain(FB_EARLY_EVENT_BLANK, &event);
-+
- if (info->fbops->fb_blank)
- ret = info->fbops->fb_blank(blank, info);
-
- if (!ret)
- fb_notifier_call_chain(FB_EVENT_BLANK, &event);
-+ else {
-+ /*
-+ * if fb_blank is failed then revert effects of
-+ * the early blank event.
-+ */
-+ if (!early_ret)
-+ fb_notifier_call_chain(FB_R_EARLY_EVENT_BLANK, &event);
-+ }
-
- return ret;
- }
-diff --git a/include/linux/fb.h b/include/linux/fb.h
-index 3da9584..5ac24d0 100644
---- a/include/linux/fb.h
-+++ b/include/linux/fb.h
-@@ -137,6 +137,11 @@ struct fb_cursor_user {
- /* A display blank is requested */
- #define FB_EVENT_BLANK 0x09
-
-+/* A hardware display blank early change occured */
-+#define FB_EARLY_EVENT_BLANK 0x10
-+/* A hardware display blank revert early change occured */
-+#define FB_R_EARLY_EVENT_BLANK 0x11
-+
- struct fb_event {
- struct fb_info *info;
- void *data;
diff --git a/sys-kernel/pinephone-pro-sources/files/0010-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0010-bootsplash.patch
deleted file mode 100644
index e5c1fd0..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0010-bootsplash.patch
+++ /dev/null
@@ -1,321 +0,0 @@
-diff --git a/Documentation/ABI/testing/sysfs-platform-bootsplash b/Documentation/ABI/testing/sysfs-platform-bootsplash
-new file mode 100644
-index 000000000000..742c7b035ded
---- /dev/null
-+++ b/Documentation/ABI/testing/sysfs-platform-bootsplash
-@@ -0,0 +1,11 @@
-+What: /sys/devices/platform/bootsplash.0/enabled
-+Date: Oct 2017
-+KernelVersion: 4.14
-+Contact: Max Staudt
-+Description:
-+ Can be set and read.
-+
-+ 0: Splash is disabled.
-+ 1: Splash is shown whenever fbcon would show a text console
-+ (i.e. no graphical application is running), and a splash
-+ file is loaded.
-diff --git a/Documentation/bootsplash.rst b/Documentation/bootsplash.rst
-new file mode 100644
-index 000000000000..611f0c558925
---- /dev/null
-+++ b/Documentation/bootsplash.rst
-@@ -0,0 +1,285 @@
-+====================
-+The Linux bootsplash
-+====================
-+
-+:Date: November, 2017
-+:Author: Max Staudt
-+
-+
-+The Linux bootsplash is a graphical replacement for the '``quiet``' boot
-+option, typically showing a logo and a spinner animation as the system starts.
-+
-+Currently, it is a part of the Framebuffer Console support, and can be found
-+as ``CONFIG_BOOTSPLASH`` in the kernel configuration. This means that as long
-+as it is enabled, it hijacks fbcon's output and draws a splash screen instead.
-+
-+Purely compiling in the bootsplash will not render it functional - to actually
-+render a splash, you will also need a splash theme file. See the example
-+utility and script in ``tools/bootsplash`` for a live demo.
-+
-+
-+
-+Motivation
-+==========
-+
-+- The '``quiet``' boot option only suppresses most messages during boot, but
-+ errors are still shown.
-+
-+- A user space implementation can only show a logo once user space has been
-+ initialized far enough to allow this. A kernel splash can display a splash
-+ immediately as soon as fbcon can be displayed.
-+
-+- Implementing a splash screen in user space (e.g. Plymouth) is problematic
-+ due to resource conflicts.
-+
-+ For example, if Plymouth is keeping ``/dev/fb0`` (provided via vesafb/efifb)
-+ open, then most DRM drivers can't replace it because the address space is
-+ still busy - thus leading to a VRAM reservation error.
-+
-+ See: https://bugzilla.opensuse.org/show_bug.cgi?id=980750
-+
-+
-+
-+Command line arguments
-+======================
-+
-+``bootsplash.bootfile``
-+ Which file in the initramfs to load.
-+
-+ The splash theme is loaded via request_firmware(), thus to load
-+ ``/lib/firmware/bootsplash/mytheme`` pass the command line:
-+
-+ ``bootsplash.bootfile=bootsplash/mytheme``
-+
-+ Note: The splash file *has to be* in the initramfs, as it needs to be
-+ available when the splash is initialized early on.
-+
-+ Default: none, i.e. a non-functional splash, falling back to showing text.
-+
-+
-+
-+sysfs run-time configuration
-+============================
-+
-+``/sys/devices/platform/bootsplash.0/enabled``
-+ Enable/disable the bootsplash.
-+ The system boots with this set to 1, but will not show a splash unless
-+ a splash theme file is also loaded.
-+
-+
-+
-+Kconfig
-+=======
-+
-+``BOOTSPLASH``
-+ Whether to compile in bootsplash support
-+ (depends on fbcon compiled in, i.e. ``FRAMEBUFFER_CONSOLE=y``)
-+
-+
-+
-+Bootsplash file format
-+======================
-+
-+A file specified in the kernel configuration as ``CONFIG_BOOTSPLASH_FILE``
-+or specified on the command line as ``bootsplash.bootfile`` will be loaded
-+and displayed as soon as fbcon is initialized.
-+
-+
-+Main blocks
-+-----------
-+
-+There are 3 main blocks in each file:
-+
-+ - one File header
-+ - n Picture headers
-+ - m (Blob header + payload) blocks
-+
-+
-+Structures
-+----------
-+
-+The on-disk structures are defined in
-+``drivers/video/fbdev/core/bootsplash_file.h`` and represent these blocks:
-+
-+ - ``struct splash_file_header``
-+
-+ Represents the file header, with splash-wide information including:
-+
-+ - The magic string "``Linux bootsplash``" on big-endian platforms
-+ (the reverse on little endian)
-+ - The file format version (for incompatible updates, hopefully never)
-+ - The background color
-+ - Number of picture and blob blocks
-+ - Animation speed (we only allow one delay for all animations)
-+
-+ The file header is followed by the first picture header.
-+
-+
-+ - ``struct splash_picture_header``
-+
-+ Represents an object (picture) drawn on screen, including its immutable
-+ properties:
-+ - Width, height
-+ - Positioning relative to screen corners or in the center
-+ - Animation, if any
-+ - Animation type
-+ - Number of blobs
-+
-+ The picture header is followed by another picture header, up until n
-+ picture headers (as defined in the file header) have been read. Then,
-+ the (blob header, payload) pairs follow.
-+
-+
-+ - ``struct splash_blob_header``
-+ (followed by payload)
-+
-+ Represents one raw data stream. So far, only picture data is defined.
-+
-+ The blob header is followed by a payload, then padding to n*16 bytes,
-+ then (if further blobs are defined in the file header) a further blob
-+ header.
-+
-+
-+Alignment
-+---------
-+
-+The bootsplash file is designed to be loaded into memory as-is.
-+
-+All structures are a multiple of 16 bytes long, all elements therein are
-+aligned to multiples of their length, and the payloads are always padded
-+up to multiples of 16 bytes. This is to allow aligned accesses in all
-+cases while still simply mapping the structures over an in-memory copy of
-+the bootsplash file.
-+
-+
-+Further information
-+-------------------
-+
-+Please see ``drivers/video/fbdev/core/bootsplash_file.h`` for further
-+details and possible values in the file.
-+
-+
-+
-+Hooks - how the bootsplash is integrated
-+========================================
-+
-+``drivers/video/fbdev/core/fbcon.c``
-+ ``fbcon_init()`` calls ``bootsplash_init()``, which loads the default
-+ bootsplash file or the one specified on the kernel command line.
-+
-+ ``fbcon_switch()`` draws the bootsplash when it's active, and is also
-+ one of the callers of ``set_blitting_type()``.
-+
-+ ``set_blitting_type()`` calls ``fbcon_set_dummyops()`` when the
-+ bootsplash is active, overriding the text rendering functions.
-+
-+ ``fbcon_cursor()`` will call ``bootsplash_disable()`` when an oops is
-+ being printed in order to make a kernel panic visible.
-+
-+``drivers/video/fbdev/core/dummyblit.c``
-+ This contains the dummy text rendering functions used to suppress text
-+ output while the bootsplash is shown.
-+
-+``drivers/tty/vt/keyboard.c``
-+ ``kbd_keycode()`` can call ``bootsplash_disable()`` when the user
-+ presses ESC or F1-F12 (changing VT). This is to provide a built-in way
-+ of disabling the splash manually at any time.
-+
-+
-+
-+FAQ: Frequently Asked Questions
-+===============================
-+
-+I want to see the log! How do I show the log?
-+---------------------------------------------
-+
-+Press ESC while the splash is shown, or remove the ``bootsplash.bootfile``
-+parameter from the kernel cmdline. Without that parameter, the bootsplash
-+will boot disabled.
-+
-+
-+Why use FB instead of modern DRM/KMS?
-+-------------------------------------
-+
-+This is a semantic problem:
-+ - What memory to draw the splash to?
-+ - And what mode will the screen be set to?
-+
-+Using the fbdev emulation solves these issues.
-+
-+Let's start from a bare KMS system, without fbcon, and without fbdev
-+emulation. In this case, as long as userspace doesn't open the KMS
-+device, the state of the screen is undefined. No framebuffer is
-+allocated in video RAM, and no particular mode is set.
-+
-+In this case, we'd have to allocate a framebuffer to show the splash,
-+and set our mode ourselves. This either wastes a screenful of video RAM
-+if the splash is to co-exist with the userspace program's own allocated
-+framebuffer, or there is a flicker as we deactivate and delete the
-+bootsplash's framebuffer and hand control over to userspace. Since we
-+may set a different mode than userspace, we'd also have flicker due
-+to mode switching.
-+
-+This logic is already contained in every KMS driver that performs fbdev
-+emulation. So we might as well use that. And the correct API to do so is
-+fbdev. Plus, we get compatibility with old, pure fbdev drivers for free.
-+With the fbdev emulation, there is *always* a well-defined framebuffer
-+to draw on. And the selection of mode has already been done by the
-+graphics driver, so we don't need to reinvent that wheel, either.
-+Finally, if userspace decides to use /dev/fbX, we don't have to worry
-+about wasting video RAM, either.
-+
-+
-+Why is the bootsplash integrated in fbcon?
-+------------------------------------------
-+
-+Right now, the bootsplash is drawn from within fbcon, as this allows us
-+to easily know *when* to draw - i.e. when we're safe from fbcon and
-+userspace drawing all over our beautiful splash logo.
-+
-+Separating them is not easy - see the to-do list below.
-+
-+
-+
-+TO DO list for future development
-+=================================
-+
-+Second enable/disable switch for the system
-+-------------------------------------------
-+
-+It may be helpful to differentiate between the system and the user
-+switching off the bootsplash. Thus, the system may make it disappear and
-+reappear e.g. for a password prompt, yet once the user has pressed ESC,
-+it could stay gone.
-+
-+
-+Fix buggy DRM/KMS drivers
-+-------------------------
-+
-+Currently, the splash code manually checks for fbdev emulation provided by
-+the ast, cirrus, and mgag200 DRM/KMS drivers.
-+These drivers use a manual mechanism similar to deferred I/O for their FB
-+emulation, and thus need to be manually flushed onto the screen in the same
-+way.
-+
-+This may be improved upon in several ways:
-+
-+1. Changing these drivers to expose the fbdev BO's memory directly, like
-+ bochsdrmfb does.
-+2. Creating a new fb_ops->fb_flush() API to allow the kernel to flush the
-+ framebuffer once the bootsplash has been drawn into it.
-+
-+
-+Separating from fbcon
-+---------------------
-+
-+Separating these two components would yield independence from fbcon being
-+compiled into the kernel, and thus lowering code size in embedded
-+applications.
-+
-+To do this cleanly will involve a clean separation of users of an FB device
-+within the kernel, i.e. fbcon, bootsplash, and userspace. Right now, the
-+legacy fbcon code and VT code co-operate to switch between fbcon and
-+userspace (by setting the VT into KD_GRAPHICS mode). Installing a muxer
-+between these components ensues refactoring of old code and checking for
-+correct locking.
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 5c237445761e..7ffac272434e 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -2709,6 +2709,8 @@ BOOTSPLASH
- M: Max Staudt
- L: linux-fbdev@vger.kernel.org
- S: Maintained
-+F: Documentation/ABI/testing/sysfs-platform-bootsplash
-+F: Documentation/bootsplash.rst
- F: drivers/video/fbdev/core/bootsplash*.*
- F: drivers/video/fbdev/core/dummycon.c
- F: include/linux/bootsplash.h
diff --git a/sys-kernel/pinephone-pro-sources/files/0010-power-rk818-Configure-rk808-clkout2-function.patch b/sys-kernel/pinephone-pro-sources/files/0010-power-rk818-Configure-rk808-clkout2-function.patch
deleted file mode 100644
index 8ff73f2..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0010-power-rk818-Configure-rk808-clkout2-function.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From: =?utf-8?q?Kamil_Trzci=C5=84ski?=
-Date: Mon, 4 Jan 2021 17:57:49 +0100
-Subject: [PATCH 11/36] power: rk818: Configure `rk808-clkout2` function
-MIME-Version: 1.0
-Content-Type: text/plain; charset="utf-8"
-Content-Transfer-Encoding: 8bit
-
-???
-
-Signed-of-by: Kamil Trzciński
----
- drivers/mfd/rk808.c | 1 +
- include/linux/mfd/rk808.h | 2 ++
- 2 files changed, 3 insertions(+)
-
-diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
-index b181fe4..1a6857e 100644
---- a/drivers/mfd/rk808.c
-+++ b/drivers/mfd/rk808.c
-@@ -303,6 +303,7 @@ static const struct rk808_reg_data rk818_pre_init_reg[] = {
- { 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/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
-index a96e6d4..2ec0520 100644
---- a/include/linux/mfd/rk808.h
-+++ b/include/linux/mfd/rk808.h
-@@ -381,6 +381,8 @@ enum rk805_reg {
-
- #define VOUT_LO_INT BIT(0)
- #define CLK32KOUT2_EN BIT(0)
-+#define CLK32KOUT2_FUNC (0 << 1)
-+#define CLK32KOUT2_FUNC_MASK BIT(1)
-
- #define TEMP115C 0x0c
- #define TEMP_HOTDIE_MSK 0x0c
diff --git a/sys-kernel/pinephone-pro-sources/files/0011-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0011-bootsplash.patch
deleted file mode 100644
index 8e87eb4..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0011-bootsplash.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-diff --git a/Documentation/ABI/testing/sysfs-platform-bootsplash b/Documentation/ABI/testing/sysfs-platform-bootsplash
-index 742c7b035ded..f8f4b259220e 100644
---- a/Documentation/ABI/testing/sysfs-platform-bootsplash
-+++ b/Documentation/ABI/testing/sysfs-platform-bootsplash
-@@ -9,3 +9,35 @@ Description:
- 1: Splash is shown whenever fbcon would show a text console
- (i.e. no graphical application is running), and a splash
- file is loaded.
-+
-+What: /sys/devices/platform/bootsplash.0/drop_splash
-+Date: Oct 2017
-+KernelVersion: 4.14
-+Contact: Max Staudt
-+Description:
-+ Can only be set.
-+
-+ Any value written will cause the current splash theme file
-+ to be unloaded and the text console to be redrawn.
-+
-+What: /sys/devices/platform/bootsplash.0/load_file
-+Date: Oct 2017
-+KernelVersion: 4.14
-+Contact: Max Staudt
-+Description:
-+ Can only be set.
-+
-+ Any value written will cause the splash to be disabled and
-+ internal memory structures to be freed.
-+
-+ A firmware path written will cause a new theme file to be
-+ loaded and the current bootsplash to be replaced.
-+ The current enabled/disabled status is not touched.
-+ If the splash is already active, it will be redrawn.
-+
-+ The path has to be a path in /lib/firmware since
-+ request_firmware() is used to fetch the data.
-+
-+ When setting the splash from the shell, echo -n has to be
-+ used as any trailing '\n' newline will be interpreted as
-+ part of the path.
-diff --git a/Documentation/bootsplash.rst b/Documentation/bootsplash.rst
-index 611f0c558925..b35aba5093e8 100644
---- a/Documentation/bootsplash.rst
-+++ b/Documentation/bootsplash.rst
-@@ -67,6 +67,14 @@ sysfs run-time configuration
- a splash theme file is also loaded.
-
-
-+``/sys/devices/platform/bootsplash.0/drop_splash``
-+ Unload splash data and free memory.
-+
-+``/sys/devices/platform/bootsplash.0/load_file``
-+ Load a splash file from ``/lib/firmware/``.
-+ Note that trailing newlines will be interpreted as part of the file name.
-+
-+
-
- Kconfig
- =======
-diff --git a/drivers/video/fbdev/core/bootsplash.c b/drivers/video/fbdev/core/bootsplash.c
-index 13fcaabbc2ca..16cb0493629d 100644
---- a/drivers/video/fbdev/core/bootsplash.c
-+++ b/drivers/video/fbdev/core/bootsplash.c
-@@ -251,11 +251,65 @@ static ssize_t splash_store_enabled(struct device *device,
- return count;
- }
-
-+static ssize_t splash_store_drop_splash(struct device *device,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct splash_file_priv *fp;
-+
-+ if (!buf || !count || !splash_state.file)
-+ return count;
-+
-+ mutex_lock(&splash_state.data_lock);
-+ fp = splash_state.file;
-+ splash_state.file = NULL;
-+ mutex_unlock(&splash_state.data_lock);
-+
-+ /* Redraw the text console */
-+ schedule_work(&splash_state.work_redraw_vc);
-+
-+ bootsplash_free_file(fp);
-+
-+ return count;
-+}
-+
-+static ssize_t splash_store_load_file(struct device *device,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct splash_file_priv *fp, *fp_old;
-+
-+ if (!count)
-+ return 0;
-+
-+ fp = bootsplash_load_firmware(&splash_state.splash_device->dev,
-+ buf);
-+
-+ if (!fp)
-+ return -ENXIO;
-+
-+ mutex_lock(&splash_state.data_lock);
-+ fp_old = splash_state.file;
-+ splash_state.splash_fb = NULL;
-+ splash_state.file = fp;
-+ mutex_unlock(&splash_state.data_lock);
-+
-+ /* Update the splash or text console */
-+ schedule_work(&splash_state.work_redraw_vc);
-+
-+ bootsplash_free_file(fp_old);
-+ return count;
-+}
-+
- static DEVICE_ATTR(enabled, 0644, splash_show_enabled, splash_store_enabled);
-+static DEVICE_ATTR(drop_splash, 0200, NULL, splash_store_drop_splash);
-+static DEVICE_ATTR(load_file, 0200, NULL, splash_store_load_file);
-
-
- static struct attribute *splash_dev_attrs[] = {
- &dev_attr_enabled.attr,
-+ &dev_attr_drop_splash.attr,
-+ &dev_attr_load_file.attr,
- NULL
- };
-
diff --git a/sys-kernel/pinephone-pro-sources/files/0011-power-rk818-battery-Add-battery-driver-for-RK818.patch b/sys-kernel/pinephone-pro-sources/files/0011-power-rk818-battery-Add-battery-driver-for-RK818.patch
deleted file mode 100644
index fd0eb7e..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0011-power-rk818-battery-Add-battery-driver-for-RK818.patch
+++ /dev/null
@@ -1,3964 +0,0 @@
-From: =?utf-8?q?Kamil_Trzci=C5=84ski?=
-Date: Sun, 3 Jan 2021 11:43:38 +0100
-Subject: [PATCH 12/36] power: rk818-battery: Add battery driver for RK818
-MIME-Version: 1.0
-Content-Type: text/plain; charset="utf-8"
-Content-Transfer-Encoding: 8bit
-
-This is forward ported driver from Rockchip BSP.
-
-Signed-of-by: Kamil Trzciński
----
- drivers/mfd/rk808.c | 40 +-
- drivers/power/supply/Kconfig | 8 +
- drivers/power/supply/Makefile | 1 +
- drivers/power/supply/rk818_battery.c | 3568 ++++++++++++++++++++++++++++++++++
- drivers/power/supply/rk818_battery.h | 168 ++
- include/linux/mfd/rk808.h | 81 +-
- 6 files changed, 3863 insertions(+), 3 deletions(-)
- create mode 100644 drivers/power/supply/rk818_battery.c
- create mode 100644 drivers/power/supply/rk818_battery.h
-
-diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
-index 1a6857e..7d1f000 100644
---- a/drivers/mfd/rk808.c
-+++ b/drivers/mfd/rk808.c
-@@ -76,12 +76,47 @@ static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
- return true;
- }
-
-+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 = {
-@@ -170,6 +205,7 @@ static const struct mfd_cell rk817s[] = {
- static const struct mfd_cell rk818s[] = {
- { .name = "rk808-clkout", },
- { .name = "rk808-regulator", },
-+ { .name = "rk818-battery", .of_compatible = "rk818-battery", },
- {
- .name = "rk808-rtc",
- .num_resources = ARRAY_SIZE(rtc_resources),
-diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
-index 5cf5bb5..f5d4434 100644
---- a/drivers/power/supply/Kconfig
-+++ b/drivers/power/supply/Kconfig
-@@ -854,4 +854,12 @@ config CHARGER_SURFACE
- Microsoft Surface devices, i.e. Surface Pro 7, Surface Laptop 3,
- Surface Book 3, and Surface Laptop Go.
-
-+config BATTERY_RK818
-+ bool "RK818 Battery driver"
-+ depends on MFD_RK808
-+ default n
-+ help
-+ If you say yes here you will get support for the battery of RK818 PMIC.
-+ This driver can give support for Rk818 Battery Charge Interface.
-+
- endif # POWER_SUPPLY
-diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
-index 4e55a11aab..1c725ee 100644
---- a/drivers/power/supply/Makefile
-+++ b/drivers/power/supply/Makefile
-@@ -104,3 +104,4 @@ obj-$(CONFIG_RN5T618_POWER) += rn5t618_power.o
- obj-$(CONFIG_BATTERY_ACER_A500) += acer_a500_battery.o
- obj-$(CONFIG_BATTERY_SURFACE) += surface_battery.o
- obj-$(CONFIG_CHARGER_SURFACE) += surface_charger.o
-+obj-$(CONFIG_BATTERY_RK818) += rk818_battery.o
-diff --git a/drivers/power/supply/rk818_battery.c b/drivers/power/supply/rk818_battery.c
-new file mode 100644
-index 00000000..f09f456
---- /dev/null
-+++ b/drivers/power/supply/rk818_battery.c
-@@ -0,0 +1,3568 @@
-+/*
-+ * rk818 battery driver
-+ *
-+ * Copyright (C) 2016 Rockchip Electronics Co., Ltd
-+ * chenjh
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope 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.
-+ *
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+//#include
-+#include
-+//#include
-+#include
-+#include
-+#include
-+//#include
-+#include
-+#include "rk818_battery.h"
-+
-+static int dbg_enable = 0;
-+module_param_named(dbg_level, dbg_enable, int, 0644);
-+
-+#define DBG(args...) \
-+ do { \
-+ if (dbg_enable) { \
-+ pr_info(args); \
-+ } \
-+ } while (0)
-+
-+#define BAT_INFO(fmt, args...) pr_info("rk818-bat: "fmt, ##args)
-+
-+/* default param */
-+#define DEFAULT_BAT_RES 135
-+#define DEFAULT_SLP_ENTER_CUR 300
-+#define DEFAULT_SLP_EXIT_CUR 300
-+#define DEFAULT_SLP_FILTER_CUR 100
-+#define DEFAULT_PWROFF_VOL_THRESD 3400
-+#define DEFAULT_MONITOR_SEC 5
-+#define DEFAULT_ALGR_VOL_THRESD1 3850
-+#define DEFAULT_ALGR_VOL_THRESD2 3950
-+#define DEFAULT_MAX_SOC_OFFSET 60
-+#define DEFAULT_FB_TEMP TEMP_105C
-+#define DEFAULT_ZERO_RESERVE_DSOC 10
-+#define DEFAULT_POFFSET 42
-+#define DEFAULT_COFFSET 0x832
-+#define DEFAULT_SAMPLE_RES 20
-+#define DEFAULT_ENERGY_MODE 0
-+#define INVALID_COFFSET_MIN 0x780
-+#define INVALID_COFFSET_MAX 0x980
-+#define INVALID_VOL_THRESD 2500
-+
-+/* sample resistor and division */
-+#define SAMPLE_RES_10MR 10
-+#define SAMPLE_RES_20MR 20
-+#define SAMPLE_RES_DIV1 1
-+#define SAMPLE_RES_DIV2 2
-+
-+/* virtual params */
-+#define VIRTUAL_CURRENT 1000
-+#define VIRTUAL_VOLTAGE 3888
-+#define VIRTUAL_SOC 66
-+#define VIRTUAL_PRESET 1
-+#define VIRTUAL_TEMPERATURE 188
-+#define VIRTUAL_STATUS POWER_SUPPLY_STATUS_CHARGING
-+
-+/* charge */
-+#define FINISH_CHRG_CUR1 1000
-+#define FINISH_CHRG_CUR2 1500
-+#define FINISH_MAX_SOC_DELAY 20
-+#define TERM_CHRG_DSOC 88
-+#define TERM_CHRG_CURR 600
-+#define TERM_CHRG_K 650
-+#define SIMULATE_CHRG_INTV 8
-+#define SIMULATE_CHRG_CURR 400
-+#define SIMULATE_CHRG_K 1500
-+#define FULL_CHRG_K 400
-+
-+/* zero algorithm */
-+#define PWROFF_THRESD 3400
-+#define MIN_ZERO_DSOC_ACCURACY 10 /*0.01%*/
-+#define MIN_ZERO_OVERCNT 100
-+#define MIN_ACCURACY 1
-+#define DEF_PWRPATH_RES 50
-+#define WAIT_DSOC_DROP_SEC 15
-+#define WAIT_SHTD_DROP_SEC 30
-+#define ZERO_GAP_XSOC1 10
-+#define ZERO_GAP_XSOC2 5
-+#define ZERO_GAP_XSOC3 3
-+#define ZERO_LOAD_LVL1 1400
-+#define ZERO_LOAD_LVL2 600
-+#define ZERO_GAP_CALIB 5
-+
-+#define ADC_CALIB_THRESHOLD 4
-+#define ADC_CALIB_LMT_MIN 3
-+#define ADC_CALIB_CNT 5
-+#define NTC_CALC_FACTOR 7
-+
-+/* time */
-+#define POWER_ON_SEC_BASE 1
-+#define MINUTE(x) ((x) * 60)
-+
-+/* sleep */
-+#define SLP_CURR_MAX 40
-+#define SLP_CURR_MIN 6
-+#define DISCHRG_TIME_STEP1 MINUTE(10)
-+#define DISCHRG_TIME_STEP2 MINUTE(60)
-+#define SLP_DSOC_VOL_THRESD 3600
-+#define REBOOT_PERIOD_SEC 180
-+#define REBOOT_MAX_CNT 80
-+
-+/* fcc */
-+#define MIN_FCC 500
-+
-+/* TS detect battery temperature */
-+#define ADC_CUR_MSK 0x03
-+#define ADC_CUR_20UA 0x00
-+#define ADC_CUR_40UA 0x01
-+#define ADC_CUR_60UA 0x02
-+#define ADC_CUR_80UA 0x03
-+
-+#define NTC_CALC_FACTOR_80UA 7
-+#define NTC_CALC_FACTOR_60UA 9
-+#define NTC_CALC_FACTOR_40UA 13
-+#define NTC_CALC_FACTOR_20UA 27
-+#define NTC_80UA_MAX_MEASURE 27500
-+#define NTC_60UA_MAX_MEASURE 36666
-+#define NTC_40UA_MAX_MEASURE 55000
-+#define NTC_20UA_MAX_MEASURE 110000
-+
-+static const char *bat_status[] = {
-+ "charge off", "dead charge", "trickle charge", "cc cv",
-+ "finish", "usb over vol", "bat temp error", "timer error",
-+};
-+
-+struct rk818_battery {
-+ struct platform_device *pdev;
-+ struct rk808 *rk818;
-+ struct regmap *regmap;
-+ struct device *dev;
-+ struct power_supply *bat;
-+ struct power_supply *usb_psy;
-+ struct power_supply *ac_psy;
-+ struct battery_platform_data *pdata;
-+ struct workqueue_struct *bat_monitor_wq;
-+ struct delayed_work bat_delay_work;
-+ struct delayed_work calib_delay_work;
-+ // struct wake_lock wake_lock;
-+ struct notifier_block fb_nb;
-+ struct timer_list caltimer;
-+ time64_t rtc_base;
-+ int bat_res;
-+ int chrg_status;
-+ bool is_initialized;
-+ bool is_first_power_on;
-+ u8 res_div;
-+ int current_max;
-+ int voltage_max;
-+ int current_avg;
-+ int voltage_avg;
-+ int voltage_ocv;
-+ int voltage_relax;
-+ int voltage_k;
-+ int voltage_b;
-+ int remain_cap;
-+ int design_cap;
-+ int nac;
-+ int fcc;
-+ int qmax;
-+ int dsoc;
-+ int rsoc;
-+ int poffset;
-+ int age_ocv_soc;
-+ bool age_allow_update;
-+ int age_level;
-+ int age_ocv_cap;
-+ int age_voltage;
-+ int age_adjust_cap;
-+ unsigned long age_keep_sec;
-+ int zero_timeout_cnt;
-+ int zero_remain_cap;
-+ int zero_dsoc;
-+ int zero_linek;
-+ u64 zero_drop_sec;
-+ u64 shtd_drop_sec;
-+ int sm_remain_cap;
-+ int sm_linek;
-+ int sm_chrg_dsoc;
-+ int sm_dischrg_dsoc;
-+ int algo_rest_val;
-+ int algo_rest_mode;
-+ int sleep_sum_cap;
-+ int sleep_remain_cap;
-+ unsigned long sleep_dischrg_sec;
-+ unsigned long sleep_sum_sec;
-+ bool sleep_chrg_online;
-+ u8 sleep_chrg_status;
-+ bool adc_allow_update;
-+ int fb_blank;
-+ bool s2r; /*suspend to resume*/
-+ u32 work_mode;
-+ int temperature;
-+ u32 monitor_ms;
-+ u32 pwroff_min;
-+ u32 adc_calib_cnt;
-+ unsigned long finish_base;
-+ unsigned long boot_base;
-+ unsigned long flat_match_sec;
-+ unsigned long plug_in_base;
-+ unsigned long plug_out_base;
-+ u8 halt_cnt;
-+ bool is_halt;
-+ bool is_max_soc_offset;
-+ bool is_sw_reset;
-+ bool is_ocv_calib;
-+ bool is_first_on;
-+ bool is_force_calib;
-+ int last_dsoc;
-+ int ocv_pre_dsoc;
-+ int ocv_new_dsoc;
-+ int max_pre_dsoc;
-+ int max_new_dsoc;
-+ int force_pre_dsoc;
-+ int force_new_dsoc;
-+ int dbg_cap_low0;
-+ int dbg_pwr_dsoc;
-+ int dbg_pwr_rsoc;
-+ int dbg_pwr_vol;
-+ int dbg_chrg_min[10];
-+ int dbg_meet_soc;
-+ int dbg_calc_dsoc;
-+ int dbg_calc_rsoc;
-+ u8 ac_in;
-+ u8 usb_in;
-+ int is_charging;
-+ unsigned long charge_count;
-+};
-+
-+#define DIV(x) ((x) ? (x) : 1)
-+
-+static void rk_send_wakeup_key(void)
-+{
-+ // TODO: WHAT TO DO HERE?
-+}
-+
-+static u64 get_boot_sec(void)
-+{
-+ struct timespec64 ts;
-+
-+ ktime_get_boottime_ts64(&ts);
-+
-+ return ts.tv_sec;
-+}
-+
-+static unsigned long base2sec(unsigned long x)
-+{
-+ if (x)
-+ return (get_boot_sec() > x) ? (get_boot_sec() - x) : 0;
-+ else
-+ return 0;
-+}
-+
-+static unsigned long base2min(unsigned long x)
-+{
-+ return base2sec(x) / 60;
-+}
-+
-+static u32 interpolate(int value, u32 *table, int size)
-+{
-+ u8 i;
-+ u16 d;
-+
-+ for (i = 0; i < size; i++) {
-+ if (value < table[i])
-+ break;
-+ }
-+
-+ if ((i > 0) && (i < size)) {
-+ d = (value - table[i - 1]) * (MAX_INTERPOLATE / (size - 1));
-+ d /= table[i] - table[i - 1];
-+ d = d + (i - 1) * (MAX_INTERPOLATE / (size - 1));
-+ } else {
-+ d = i * ((MAX_INTERPOLATE + size / 2) / size);
-+ }
-+
-+ if (d > 1000)
-+ d = 1000;
-+
-+ return d;
-+}
-+
-+/* (a*b)/c */
-+static int32_t ab_div_c(u32 a, u32 b, u32 c)
-+{
-+ bool sign;
-+ u32 ans = MAX_INT;
-+ int tmp;
-+
-+ sign = ((((a ^ b) ^ c) & 0x80000000) != 0);
-+ if (c != 0) {
-+ if (sign)
-+ c = -c;
-+ tmp = (a * b + (c >> 1)) / c;
-+ if (tmp < MAX_INT)
-+ ans = tmp;
-+ }
-+
-+ if (sign)
-+ ans = -ans;
-+
-+ return ans;
-+}
-+
-+static int rk818_bat_read(struct rk818_battery *di, u8 reg)
-+{
-+ int ret, val;
-+
-+ ret = regmap_read(di->regmap, reg, &val);
-+ if (ret)
-+ dev_err(di->dev, "read reg:0x%x failed\n", reg);
-+
-+ return val;
-+}
-+
-+static int rk818_bat_write(struct rk818_battery *di, u8 reg, u8 buf)
-+{
-+ int ret;
-+
-+ ret = regmap_write(di->regmap, reg, buf);
-+ if (ret)
-+ dev_err(di->dev, "i2c write reg: 0x%2x error\n", reg);
-+
-+ return ret;
-+}
-+
-+static int rk818_bat_set_bits(struct rk818_battery *di, u8 reg, u8 mask, u8 buf)
-+{
-+ int ret;
-+
-+ ret = regmap_update_bits(di->regmap, reg, mask, buf);
-+ if (ret)
-+ dev_err(di->dev, "write reg:0x%x failed\n", reg);
-+
-+ return ret;
-+}
-+
-+static int rk818_bat_clear_bits(struct rk818_battery *di, u8 reg, u8 mask)
-+{
-+ int ret;
-+
-+ ret = regmap_update_bits(di->regmap, reg, mask, 0);
-+ if (ret)
-+ dev_err(di->dev, "clr reg:0x%02x failed\n", reg);
-+
-+ return ret;
-+}
-+
-+static void rk818_bat_dump_regs(struct rk818_battery *di, u8 start, u8 end)
-+{
-+ int i;
-+
-+ if (!dbg_enable)
-+ return;
-+
-+ DBG("dump regs from: 0x%x-->0x%x\n", start, end);
-+ for (i = start; i < end; i++)
-+ DBG("0x%x: 0x%0x\n", i, rk818_bat_read(di, i));
-+}
-+
-+static bool rk818_bat_chrg_online(struct rk818_battery *di)
-+{
-+ u8 buf;
-+
-+ buf = rk818_bat_read(di, RK818_VB_MON_REG);
-+
-+ return (buf & PLUG_IN_STS) ? true : false;
-+}
-+
-+static int rk818_bat_get_coulomb_cap(struct rk818_battery *di)
-+{
-+ int val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_GASCNT3_REG) << 24;
-+ val |= rk818_bat_read(di, RK818_GASCNT2_REG) << 16;
-+ val |= rk818_bat_read(di, RK818_GASCNT1_REG) << 8;
-+ val |= rk818_bat_read(di, RK818_GASCNT0_REG) << 0;
-+
-+ return (val / 2390) * di->res_div;
-+}
-+
-+static int rk818_bat_get_rsoc(struct rk818_battery *di)
-+{
-+ int remain_cap;
-+
-+ remain_cap = rk818_bat_get_coulomb_cap(di);
-+ return (remain_cap + di->fcc / 200) * 100 / DIV(di->fcc);
-+}
-+
-+static ssize_t bat_info_store(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ char cmd;
-+ struct rk818_battery *di = dev_get_drvdata(dev);
-+
-+ sscanf(buf, "%c", &cmd);
-+
-+ if (cmd == 'n')
-+ rk818_bat_set_bits(di, RK818_MISC_MARK_REG,
-+ FG_RESET_NOW, FG_RESET_NOW);
-+ else if (cmd == 'm')
-+ rk818_bat_set_bits(di, RK818_MISC_MARK_REG,
-+ FG_RESET_LATE, FG_RESET_LATE);
-+ else if (cmd == 'c')
-+ rk818_bat_clear_bits(di, RK818_MISC_MARK_REG,
-+ FG_RESET_LATE | FG_RESET_NOW);
-+ else if (cmd == 'r')
-+ BAT_INFO("0x%2x\n", rk818_bat_read(di, RK818_MISC_MARK_REG));
-+ else
-+ BAT_INFO("command error\n");
-+
-+ return count;
-+}
-+
-+static struct device_attribute rk818_bat_attr[] = {
-+ __ATTR(bat, 0664, NULL, bat_info_store),
-+};
-+
-+static void rk818_bat_enable_gauge(struct rk818_battery *di)
-+{
-+ u8 buf;
-+
-+ buf = rk818_bat_read(di, RK818_TS_CTRL_REG);
-+ buf |= GG_EN;
-+ rk818_bat_write(di, RK818_TS_CTRL_REG, buf);
-+}
-+
-+static void rk818_bat_save_age_level(struct rk818_battery *di, u8 level)
-+{
-+ rk818_bat_write(di, RK818_UPDAT_LEVE_REG, level);
-+}
-+
-+static u8 rk818_bat_get_age_level(struct rk818_battery *di)
-+{
-+ return rk818_bat_read(di, RK818_UPDAT_LEVE_REG);
-+}
-+
-+static int rk818_bat_get_vcalib0(struct rk818_battery *di)
-+{
-+ int val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_VCALIB0_REGL) << 0;
-+ val |= rk818_bat_read(di, RK818_VCALIB0_REGH) << 8;
-+
-+ DBG("<%s>. voffset0: 0x%x\n", __func__, val);
-+ return val;
-+}
-+
-+static int rk818_bat_get_vcalib1(struct rk818_battery *di)
-+{
-+ int val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_VCALIB1_REGL) << 0;
-+ val |= rk818_bat_read(di, RK818_VCALIB1_REGH) << 8;
-+
-+ DBG("<%s>. voffset1: 0x%x\n", __func__, val);
-+ return val;
-+}
-+
-+static int rk818_bat_get_ioffset(struct rk818_battery *di)
-+{
-+ int val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_IOFFSET_REGL) << 0;
-+ val |= rk818_bat_read(di, RK818_IOFFSET_REGH) << 8;
-+
-+ DBG("<%s>. ioffset: 0x%x\n", __func__, val);
-+ return val;
-+}
-+
-+static int rk818_bat_get_coffset(struct rk818_battery *di)
-+{
-+ int val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_CAL_OFFSET_REGL) << 0;
-+ val |= rk818_bat_read(di, RK818_CAL_OFFSET_REGH) << 8;
-+
-+ DBG("<%s>. coffset: 0x%x\n", __func__, val);
-+ return val;
-+}
-+
-+static void rk818_bat_set_coffset(struct rk818_battery *di, int val)
-+{
-+ u8 buf;
-+
-+ if ((val < INVALID_COFFSET_MIN) || (val > INVALID_COFFSET_MAX)) {
-+ BAT_INFO("set invalid coffset=0x%x\n", val);
-+ return;
-+ }
-+
-+ buf = (val >> 8) & 0xff;
-+ rk818_bat_write(di, RK818_CAL_OFFSET_REGH, buf);
-+ buf = (val >> 0) & 0xff;
-+ rk818_bat_write(di, RK818_CAL_OFFSET_REGL, buf);
-+ DBG("<%s>. coffset: 0x%x\n", __func__, val);
-+}
-+
-+static void rk818_bat_init_voltage_kb(struct rk818_battery *di)
-+{
-+ int vcalib0, vcalib1;
-+
-+ vcalib0 = rk818_bat_get_vcalib0(di);
-+ vcalib1 = rk818_bat_get_vcalib1(di);
-+ di->voltage_k = (4200 - 3000) * 1000 / DIV(vcalib1 - vcalib0);
-+ di->voltage_b = 4200 - (di->voltage_k * vcalib1) / 1000;
-+
-+ DBG("voltage_k=%d(*1000),voltage_b=%d\n", di->voltage_k, di->voltage_b);
-+}
-+
-+static int rk818_bat_get_ocv_voltage(struct rk818_battery *di)
-+{
-+ int vol, val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_BAT_OCV_REGL) << 0;
-+ val |= rk818_bat_read(di, RK818_BAT_OCV_REGH) << 8;
-+
-+ vol = di->voltage_k * val / 1000 + di->voltage_b;
-+
-+ return vol;
-+}
-+
-+static int rk818_bat_get_avg_voltage(struct rk818_battery *di)
-+{
-+ int vol, val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_BAT_VOL_REGL) << 0;
-+ val |= rk818_bat_read(di, RK818_BAT_VOL_REGH) << 8;
-+
-+ vol = di->voltage_k * val / 1000 + di->voltage_b;
-+
-+ return vol;
-+}
-+
-+static bool is_rk818_bat_relax_mode(struct rk818_battery *di)
-+{
-+ u8 status;
-+
-+ status = rk818_bat_read(di, RK818_GGSTS_REG);
-+ if (!(status & RELAX_VOL1_UPD) || !(status & RELAX_VOL2_UPD))
-+ return false;
-+ else
-+ return true;
-+}
-+
-+static u16 rk818_bat_get_relax_vol1(struct rk818_battery *di)
-+{
-+ u16 vol, val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_RELAX_VOL1_REGL) << 0;
-+ val |= rk818_bat_read(di, RK818_RELAX_VOL1_REGH) << 8;
-+ vol = di->voltage_k * val / 1000 + di->voltage_b;
-+
-+ return vol;
-+}
-+
-+static u16 rk818_bat_get_relax_vol2(struct rk818_battery *di)
-+{
-+ u16 vol, val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_RELAX_VOL2_REGL) << 0;
-+ val |= rk818_bat_read(di, RK818_RELAX_VOL2_REGH) << 8;
-+ vol = di->voltage_k * val / 1000 + di->voltage_b;
-+
-+ return vol;
-+}
-+
-+static u16 rk818_bat_get_relax_voltage(struct rk818_battery *di)
-+{
-+ u16 relax_vol1, relax_vol2;
-+
-+ if (!is_rk818_bat_relax_mode(di))
-+ return 0;
-+
-+ relax_vol1 = rk818_bat_get_relax_vol1(di);
-+ relax_vol2 = rk818_bat_get_relax_vol2(di);
-+
-+ return relax_vol1 > relax_vol2 ? relax_vol1 : relax_vol2;
-+}
-+
-+static int rk818_bat_get_avg_current(struct rk818_battery *di)
-+{
-+ int cur, val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_BAT_CUR_AVG_REGL) << 0;
-+ val |= rk818_bat_read(di, RK818_BAT_CUR_AVG_REGH) << 8;
-+
-+ if (val & 0x800)
-+ val -= 4096;
-+ cur = val * di->res_div * 1506 / 1000;
-+
-+ return cur;
-+}
-+
-+static int rk818_bat_vol_to_ocvsoc(struct rk818_battery *di, int voltage)
-+{
-+ u32 *ocv_table, temp;
-+ int ocv_size, ocv_soc;
-+
-+ ocv_table = di->pdata->ocv_table;
-+ ocv_size = di->pdata->ocv_size;
-+ temp = interpolate(voltage, ocv_table, ocv_size);
-+ ocv_soc = ab_div_c(temp, MAX_PERCENTAGE, MAX_INTERPOLATE);
-+
-+ return ocv_soc;
-+}
-+
-+static int rk818_bat_vol_to_ocvcap(struct rk818_battery *di, int voltage)
-+{
-+ u32 *ocv_table, temp;
-+ int ocv_size, cap;
-+
-+ ocv_table = di->pdata->ocv_table;
-+ ocv_size = di->pdata->ocv_size;
-+ temp = interpolate(voltage, ocv_table, ocv_size);
-+ cap = ab_div_c(temp, di->fcc, MAX_INTERPOLATE);
-+
-+ return cap;
-+}
-+
-+static int rk818_bat_vol_to_zerosoc(struct rk818_battery *di, int voltage)
-+{
-+ u32 *ocv_table, temp;
-+ int ocv_size, ocv_soc;
-+
-+ ocv_table = di->pdata->zero_table;
-+ ocv_size = di->pdata->ocv_size;
-+ temp = interpolate(voltage, ocv_table, ocv_size);
-+ ocv_soc = ab_div_c(temp, MAX_PERCENTAGE, MAX_INTERPOLATE);
-+
-+ return ocv_soc;
-+}
-+
-+static int rk818_bat_vol_to_zerocap(struct rk818_battery *di, int voltage)
-+{
-+ u32 *ocv_table, temp;
-+ int ocv_size, cap;
-+
-+ ocv_table = di->pdata->zero_table;
-+ ocv_size = di->pdata->ocv_size;
-+ temp = interpolate(voltage, ocv_table, ocv_size);
-+ cap = ab_div_c(temp, di->fcc, MAX_INTERPOLATE);
-+
-+ return cap;
-+}
-+
-+static int rk818_bat_get_iadc(struct rk818_battery *di)
-+{
-+ int val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_BAT_CUR_AVG_REGL) << 0;
-+ val |= rk818_bat_read(di, RK818_BAT_CUR_AVG_REGH) << 8;
-+ if (val > 2047)
-+ val -= 4096;
-+
-+ return val;
-+}
-+
-+static bool rk818_bat_adc_calib(struct rk818_battery *di)
-+{
-+ int i, ioffset, coffset, adc, save_coffset;
-+
-+ if ((di->chrg_status != CHARGE_FINISH) ||
-+ (di->adc_calib_cnt > ADC_CALIB_CNT) ||
-+ (base2min(di->boot_base) < ADC_CALIB_LMT_MIN) ||
-+ (abs(di->current_avg) < ADC_CALIB_THRESHOLD))
-+ return false;
-+
-+ di->adc_calib_cnt++;
-+ save_coffset = rk818_bat_get_coffset(di);
-+ for (i = 0; i < 5; i++) {
-+ adc = rk818_bat_get_iadc(di);
-+ if (!rk818_bat_chrg_online(di)) {
-+ rk818_bat_set_coffset(di, save_coffset);
-+ BAT_INFO("quit, charger plugout when calib adc\n");
-+ return false;
-+ }
-+ coffset = rk818_bat_get_coffset(di);
-+ rk818_bat_set_coffset(di, coffset + adc);
-+ msleep(2000);
-+ adc = rk818_bat_get_iadc(di);
-+ if (abs(adc) < ADC_CALIB_THRESHOLD) {
-+ coffset = rk818_bat_get_coffset(di);
-+ ioffset = rk818_bat_get_ioffset(di);
-+ di->poffset = coffset - ioffset;
-+ rk818_bat_write(di, RK818_POFFSET_REG, di->poffset);
-+ BAT_INFO("new offset:c=0x%x, i=0x%x, p=0x%x\n",
-+ coffset, ioffset, di->poffset);
-+ return true;
-+ } else {
-+ BAT_INFO("coffset calib again %d.., max_cnt=%d\n",
-+ i, di->adc_calib_cnt);
-+ rk818_bat_set_coffset(di, coffset);
-+ msleep(2000);
-+ }
-+ }
-+
-+ rk818_bat_set_coffset(di, save_coffset);
-+
-+ return false;
-+}
-+
-+static void rk818_bat_set_ioffset_sample(struct rk818_battery *di)
-+{
-+ u8 ggcon;
-+
-+ ggcon = rk818_bat_read(di, RK818_GGCON_REG);
-+ ggcon &= ~ADC_CAL_MIN_MSK;
-+ ggcon |= ADC_CAL_8MIN;
-+ rk818_bat_write(di, RK818_GGCON_REG, ggcon);
-+}
-+
-+static void rk818_bat_set_ocv_sample(struct rk818_battery *di)
-+{
-+ u8 ggcon;
-+
-+ ggcon = rk818_bat_read(di, RK818_GGCON_REG);
-+ ggcon &= ~OCV_SAMP_MIN_MSK;
-+ ggcon |= OCV_SAMP_8MIN;
-+ rk818_bat_write(di, RK818_GGCON_REG, ggcon);
-+}
-+
-+static void rk818_bat_restart_relax(struct rk818_battery *di)
-+{
-+ u8 ggsts;
-+
-+ ggsts = rk818_bat_read(di, RK818_GGSTS_REG);
-+ ggsts &= ~RELAX_VOL12_UPD_MSK;
-+ rk818_bat_write(di, RK818_GGSTS_REG, ggsts);
-+}
-+
-+static void rk818_bat_set_relax_sample(struct rk818_battery *di)
-+{
-+ u8 buf;
-+ int enter_thres, exit_thres;
-+ struct battery_platform_data *pdata = di->pdata;
-+
-+ enter_thres = pdata->sleep_enter_current * 1000 / 1506 / DIV(di->res_div);
-+ exit_thres = pdata->sleep_exit_current * 1000 / 1506 / DIV(di->res_div);
-+
-+ /* set relax enter and exit threshold */
-+ buf = enter_thres & 0xff;
-+ rk818_bat_write(di, RK818_RELAX_ENTRY_THRES_REGL, buf);
-+ buf = (enter_thres >> 8) & 0xff;
-+ rk818_bat_write(di, RK818_RELAX_ENTRY_THRES_REGH, buf);
-+
-+ buf = exit_thres & 0xff;
-+ rk818_bat_write(di, RK818_RELAX_EXIT_THRES_REGL, buf);
-+ buf = (exit_thres >> 8) & 0xff;
-+ rk818_bat_write(di, RK818_RELAX_EXIT_THRES_REGH, buf);
-+
-+ /* reset relax update state */
-+ rk818_bat_restart_relax(di);
-+ DBG("<%s>. sleep_enter_current = %d, sleep_exit_current = %d\n",
-+ __func__, pdata->sleep_enter_current, pdata->sleep_exit_current);
-+}
-+
-+static bool is_rk818_bat_exist(struct rk818_battery *di)
-+{
-+ return (rk818_bat_read(di, RK818_SUP_STS_REG) & BAT_EXS) ? true : false;
-+}
-+
-+static bool is_rk818_bat_first_pwron(struct rk818_battery *di)
-+{
-+ u8 buf;
-+
-+ buf = rk818_bat_read(di, RK818_GGSTS_REG);
-+ if (buf & BAT_CON) {
-+ buf &= ~BAT_CON;
-+ rk818_bat_write(di, RK818_GGSTS_REG, buf);
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+static u8 rk818_bat_get_pwroff_min(struct rk818_battery *di)
-+{
-+ u8 cur, last;
-+
-+ cur = rk818_bat_read(di, RK818_NON_ACT_TIMER_CNT_REG);
-+ last = rk818_bat_read(di, RK818_NON_ACT_TIMER_CNT_SAVE_REG);
-+ rk818_bat_write(di, RK818_NON_ACT_TIMER_CNT_SAVE_REG, cur);
-+
-+ return (cur != last) ? cur : 0;
-+}
-+
-+static u8 is_rk818_bat_initialized(struct rk818_battery *di)
-+{
-+ u8 val = rk818_bat_read(di, RK818_MISC_MARK_REG);
-+
-+ if (val & FG_INIT) {
-+ val &= ~FG_INIT;
-+ rk818_bat_write(di, RK818_MISC_MARK_REG, val);
-+ return true;
-+ } else {
-+ return false;
-+ }
-+}
-+
-+static bool is_rk818_bat_ocv_valid(struct rk818_battery *di)
-+{
-+ return (!di->is_initialized && di->pwroff_min >= 30) ? true : false;
-+}
-+
-+static void rk818_bat_init_age_algorithm(struct rk818_battery *di)
-+{
-+ int age_level, ocv_soc, ocv_cap, ocv_vol;
-+
-+ if (di->is_first_power_on || is_rk818_bat_ocv_valid(di)) {
-+ DBG("<%s> enter.\n", __func__);
-+ ocv_vol = rk818_bat_get_ocv_voltage(di);
-+ ocv_soc = rk818_bat_vol_to_ocvsoc(di, ocv_vol);
-+ ocv_cap = rk818_bat_vol_to_ocvcap(di, ocv_vol);
-+ if (ocv_soc < 20) {
-+ di->age_voltage = ocv_vol;
-+ di->age_ocv_cap = ocv_cap;
-+ di->age_ocv_soc = ocv_soc;
-+ di->age_adjust_cap = 0;
-+
-+ if (ocv_soc <= 0)
-+ di->age_level = 100;
-+ else if (ocv_soc < 5)
-+ di->age_level = 95;
-+ else if (ocv_soc < 10)
-+ di->age_level = 90;
-+ else
-+ di->age_level = 80;
-+
-+ age_level = rk818_bat_get_age_level(di);
-+ if (age_level > di->age_level) {
-+ di->age_allow_update = false;
-+ age_level -= 5;
-+ if (age_level <= 80)
-+ age_level = 80;
-+ rk818_bat_save_age_level(di, age_level);
-+ } else {
-+ di->age_allow_update = true;
-+ di->age_keep_sec = get_boot_sec();
-+ }
-+
-+ BAT_INFO("init_age_algorithm: "
-+ "age_vol:%d, age_ocv_cap:%d, "
-+ "age_ocv_soc:%d, old_age_level:%d, "
-+ "age_allow_update:%d, new_age_level:%d\n",
-+ di->age_voltage, di->age_ocv_cap,
-+ ocv_soc, age_level, di->age_allow_update,
-+ di->age_level);
-+ }
-+ }
-+}
-+
-+static enum power_supply_property rk818_bat_props[] = {
-+ POWER_SUPPLY_PROP_CURRENT_NOW,
-+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
-+ POWER_SUPPLY_PROP_PRESENT,
-+ POWER_SUPPLY_PROP_HEALTH,
-+ POWER_SUPPLY_PROP_CAPACITY,
-+ POWER_SUPPLY_PROP_TEMP,
-+ POWER_SUPPLY_PROP_STATUS,
-+ POWER_SUPPLY_PROP_CHARGE_COUNTER,
-+ POWER_SUPPLY_PROP_CHARGE_FULL,
-+ POWER_SUPPLY_PROP_VOLTAGE_MAX,
-+ POWER_SUPPLY_PROP_CURRENT_MAX,
-+};
-+
-+static int rk818_bat_get_usb_psy(struct device *dev, void *data)
-+{
-+ struct rk818_battery *di = data;
-+ struct power_supply *psy = dev_get_drvdata(dev);
-+
-+ if (psy->desc->type == POWER_SUPPLY_TYPE_USB) {
-+ di->usb_psy = psy;
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int rk818_bat_get_ac_psy(struct device *dev, void *data)
-+{
-+ struct rk818_battery *di = data;
-+ struct power_supply *psy = dev_get_drvdata(dev);
-+
-+ if (psy->desc->type == POWER_SUPPLY_TYPE_MAINS) {
-+ di->ac_psy = psy;
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+static void rk818_bat_get_chrg_psy(struct rk818_battery *di)
-+{
-+ if (!di->usb_psy)
-+ class_for_each_device(power_supply_class, NULL, (void *)di,
-+ rk818_bat_get_usb_psy);
-+ if (!di->ac_psy)
-+ class_for_each_device(power_supply_class, NULL, (void *)di,
-+ rk818_bat_get_ac_psy);
-+}
-+
-+static int rk818_bat_get_charge_state(struct rk818_battery *di)
-+{
-+ union power_supply_propval val;
-+ int ret;
-+
-+ if (!di->usb_psy || !di->ac_psy)
-+ rk818_bat_get_chrg_psy(di);
-+
-+ if (di->usb_psy) {
-+ ret = di->usb_psy->desc->get_property(di->usb_psy,
-+ POWER_SUPPLY_PROP_ONLINE,
-+ &val);
-+ if (!ret)
-+ di->usb_in = val.intval;
-+ }
-+
-+ if (di->ac_psy) {
-+ ret = di->ac_psy->desc->get_property(di->ac_psy,
-+ POWER_SUPPLY_PROP_ONLINE,
-+ &val);
-+ if (!ret)
-+ di->ac_in = val.intval;
-+ }
-+
-+ DBG("%s: ac_online=%d, usb_online=%d\n",
-+ __func__, di->ac_in, di->usb_in);
-+
-+ return (di->usb_in || di->ac_in);
-+}
-+
-+static int rk818_battery_get_property(struct power_supply *psy,
-+ enum power_supply_property psp,
-+ union power_supply_propval *val)
-+{
-+ struct rk818_battery *di = power_supply_get_drvdata(psy);
-+
-+ switch (psp) {
-+ case POWER_SUPPLY_PROP_CURRENT_NOW:
-+ val->intval = di->current_avg * 1000;/*uA*/
-+ if (di->pdata->bat_mode == MODE_VIRTUAL)
-+ val->intval = VIRTUAL_CURRENT * 1000;
-+ break;
-+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-+ val->intval = di->voltage_avg * 1000;/*uV*/
-+ if (di->pdata->bat_mode == MODE_VIRTUAL)
-+ val->intval = VIRTUAL_VOLTAGE * 1000;
-+ break;
-+ case POWER_SUPPLY_PROP_PRESENT:
-+ val->intval = is_rk818_bat_exist(di);
-+ if (di->pdata->bat_mode == MODE_VIRTUAL)
-+ val->intval = VIRTUAL_PRESET;
-+ break;
-+ case POWER_SUPPLY_PROP_CAPACITY:
-+ val->intval = di->dsoc;
-+ if (di->pdata->bat_mode == MODE_VIRTUAL)
-+ val->intval = VIRTUAL_SOC;
-+ DBG("<%s>. report dsoc: %d\n", __func__, val->intval);
-+ break;
-+ case POWER_SUPPLY_PROP_HEALTH:
-+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
-+ break;
-+ case POWER_SUPPLY_PROP_TEMP:
-+ val->intval = di->temperature;
-+ if (di->pdata->bat_mode == MODE_VIRTUAL)
-+ val->intval = VIRTUAL_TEMPERATURE;
-+ break;
-+ case POWER_SUPPLY_PROP_STATUS:
-+ if (di->pdata->bat_mode == MODE_VIRTUAL)
-+ val->intval = VIRTUAL_STATUS;
-+ else if (di->dsoc == 100)
-+ val->intval = POWER_SUPPLY_STATUS_FULL;
-+ else if (rk818_bat_get_charge_state(di))
-+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
-+ else
-+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
-+ break;
-+ case POWER_SUPPLY_PROP_CHARGE_COUNTER:
-+ val->intval = di->charge_count;
-+ break;
-+ case POWER_SUPPLY_PROP_CHARGE_FULL:
-+ val->intval = di->pdata->design_capacity * 1000;/* uAh */
-+ break;
-+ case POWER_SUPPLY_PROP_VOLTAGE_MAX:
-+ val->intval = di->voltage_max * 1000; /* uV */
-+ break;
-+ case POWER_SUPPLY_PROP_CURRENT_MAX:
-+ val->intval = di->current_max * 1000; /* uA */
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct power_supply_desc rk818_bat_desc = {
-+ .name = "battery",
-+ .type = POWER_SUPPLY_TYPE_BATTERY,
-+ .properties = rk818_bat_props,
-+ .num_properties = ARRAY_SIZE(rk818_bat_props),
-+ .get_property = rk818_battery_get_property,
-+};
-+
-+static int rk818_bat_init_power_supply(struct rk818_battery *di)
-+{
-+ struct power_supply_config psy_cfg = { .drv_data = di, };
-+
-+ di->bat = devm_power_supply_register(di->dev, &rk818_bat_desc, &psy_cfg);
-+ if (IS_ERR(di->bat)) {
-+ dev_err(di->dev, "register bat power supply fail\n");
-+ return PTR_ERR(di->bat);
-+ }
-+
-+ return 0;
-+}
-+
-+static void rk818_bat_save_cap(struct rk818_battery *di, int cap)
-+{
-+ u8 buf;
-+ static u32 old_cap;
-+
-+ if (cap >= di->qmax)
-+ cap = di->qmax;
-+ if (cap <= 0)
-+ cap = 0;
-+ if (old_cap == cap)
-+ return;
-+
-+ old_cap = cap;
-+ buf = (cap >> 24) & 0xff;
-+ rk818_bat_write(di, RK818_REMAIN_CAP_REG3, buf);
-+ buf = (cap >> 16) & 0xff;
-+ rk818_bat_write(di, RK818_REMAIN_CAP_REG2, buf);
-+ buf = (cap >> 8) & 0xff;
-+ rk818_bat_write(di, RK818_REMAIN_CAP_REG1, buf);
-+ buf = (cap >> 0) & 0xff;
-+ rk818_bat_write(di, RK818_REMAIN_CAP_REG0, buf);
-+}
-+
-+static int rk818_bat_get_prev_cap(struct rk818_battery *di)
-+{
-+ int val = 0;
-+
-+ val |= rk818_bat_read(di, RK818_REMAIN_CAP_REG3) << 24;
-+ val |= rk818_bat_read(di, RK818_REMAIN_CAP_REG2) << 16;
-+ val |= rk818_bat_read(di, RK818_REMAIN_CAP_REG1) << 8;
-+ val |= rk818_bat_read(di, RK818_REMAIN_CAP_REG0) << 0;
-+
-+ return val;
-+}
-+
-+static void rk818_bat_save_fcc(struct rk818_battery *di, u32 fcc)
-+{
-+ u8 buf;
-+
-+ buf = (fcc >> 24) & 0xff;
-+ rk818_bat_write(di, RK818_NEW_FCC_REG3, buf);
-+ buf = (fcc >> 16) & 0xff;
-+ rk818_bat_write(di, RK818_NEW_FCC_REG2, buf);
-+ buf = (fcc >> 8) & 0xff;
-+ rk818_bat_write(di, RK818_NEW_FCC_REG1, buf);
-+ buf = (fcc >> 0) & 0xff;
-+ rk818_bat_write(di, RK818_NEW_FCC_REG0, buf);
-+
-+ BAT_INFO("save fcc: %d\n", fcc);
-+}
-+
-+static int rk818_bat_get_fcc(struct rk818_battery *di)
-+{
-+ u32 fcc = 0;
-+
-+ fcc |= rk818_bat_read(di, RK818_NEW_FCC_REG3) << 24;
-+ fcc |= rk818_bat_read(di, RK818_NEW_FCC_REG2) << 16;
-+ fcc |= rk818_bat_read(di, RK818_NEW_FCC_REG1) << 8;
-+ fcc |= rk818_bat_read(di, RK818_NEW_FCC_REG0) << 0;
-+
-+ if (fcc < MIN_FCC) {
-+ BAT_INFO("invalid fcc(%d), use design cap", fcc);
-+ fcc = di->pdata->design_capacity;
-+ rk818_bat_save_fcc(di, fcc);
-+ } else if (fcc > di->pdata->design_qmax) {
-+ BAT_INFO("invalid fcc(%d), use qmax", fcc);
-+ fcc = di->pdata->design_qmax;
-+ rk818_bat_save_fcc(di, fcc);
-+ }
-+
-+ return fcc;
-+}
-+
-+static void rk818_bat_init_coulomb_cap(struct rk818_battery *di, u32 capacity)
-+{
-+ u8 buf;
-+ u32 cap;
-+
-+ cap = capacity * 2390 / DIV(di->res_div);
-+ buf = (cap >> 24) & 0xff;
-+ rk818_bat_write(di, RK818_GASCNT_CAL_REG3, buf);
-+ buf = (cap >> 16) & 0xff;
-+ rk818_bat_write(di, RK818_GASCNT_CAL_REG2, buf);
-+ buf = (cap >> 8) & 0xff;
-+ rk818_bat_write(di, RK818_GASCNT_CAL_REG1, buf);
-+ buf = ((cap >> 0) & 0xff);
-+ rk818_bat_write(di, RK818_GASCNT_CAL_REG0, buf);
-+
-+ DBG("<%s>. new coulomb cap = %d\n", __func__, capacity);
-+ di->remain_cap = capacity;
-+ di->rsoc = rk818_bat_get_rsoc(di);
-+}
-+
-+static void rk818_bat_save_dsoc(struct rk818_battery *di, u8 save_soc)
-+{
-+ static int last_soc = -1;
-+
-+ if (last_soc != save_soc) {
-+ rk818_bat_write(di, RK818_SOC_REG, save_soc);
-+ last_soc = save_soc;
-+ }
-+}
-+
-+static int rk818_bat_get_prev_dsoc(struct rk818_battery *di)
-+{
-+ return rk818_bat_read(di, RK818_SOC_REG);
-+}
-+
-+static void rk818_bat_save_reboot_cnt(struct rk818_battery *di, u8 save_cnt)
-+{
-+ rk818_bat_write(di, RK818_REBOOT_CNT_REG, save_cnt);
-+}
-+
-+static int rk818_bat_fb_notifier(struct notifier_block *nb,
-+ unsigned long event, void *data)
-+{
-+ struct rk818_battery *di;
-+ struct fb_event *evdata = data;
-+
-+ if (event != FB_EARLY_EVENT_BLANK && event != FB_EVENT_BLANK)
-+ return NOTIFY_OK;
-+
-+ di = container_of(nb, struct rk818_battery, fb_nb);
-+ di->fb_blank = *(int *)evdata->data;
-+
-+ return 0;
-+}
-+
-+static int rk818_bat_register_fb_notify(struct rk818_battery *di)
-+{
-+ memset(&di->fb_nb, 0, sizeof(di->fb_nb));
-+ di->fb_nb.notifier_call = rk818_bat_fb_notifier;
-+
-+ return fb_register_client(&di->fb_nb);
-+}
-+
-+static int rk818_bat_unregister_fb_notify(struct rk818_battery *di)
-+{
-+ return fb_unregister_client(&di->fb_nb);
-+}
-+
-+static u8 rk818_bat_get_halt_cnt(struct rk818_battery *di)
-+{
-+ return rk818_bat_read(di, RK818_HALT_CNT_REG);
-+}
-+
-+static void rk818_bat_inc_halt_cnt(struct rk818_battery *di)
-+{
-+ u8 cnt;
-+
-+ cnt = rk818_bat_read(di, RK818_HALT_CNT_REG);
-+ rk818_bat_write(di, RK818_HALT_CNT_REG, ++cnt);
-+}
-+
-+static bool is_rk818_bat_last_halt(struct rk818_battery *di)
-+{
-+ int pre_cap = rk818_bat_get_prev_cap(di);
-+ int now_cap = rk818_bat_get_coulomb_cap(di);
-+
-+ /* over 10%: system halt last time */
-+ if (abs(now_cap - pre_cap) > (di->fcc / 10)) {
-+ rk818_bat_inc_halt_cnt(di);
-+ return true;
-+ } else {
-+ return false;
-+ }
-+}
-+
-+static void rk818_bat_first_pwron(struct rk818_battery *di)
-+{
-+ int ocv_vol;
-+
-+ rk818_bat_save_fcc(di, di->design_cap);
-+ ocv_vol = rk818_bat_get_ocv_voltage(di);
-+ di->fcc = rk818_bat_get_fcc(di);
-+ di->nac = rk818_bat_vol_to_ocvcap(di, ocv_vol);
-+ di->rsoc = rk818_bat_vol_to_ocvsoc(di, ocv_vol);
-+ di->dsoc = di->rsoc;
-+ di->is_first_on = true;
-+
-+ BAT_INFO("first on: dsoc=%d, rsoc=%d cap=%d, fcc=%d, ov=%d\n",
-+ di->dsoc, di->rsoc, di->nac, di->fcc, ocv_vol);
-+}
-+
-+static void rk818_bat_not_first_pwron(struct rk818_battery *di)
-+{
-+ int now_cap, pre_soc, pre_cap, ocv_cap, ocv_soc, ocv_vol;
-+
-+ di->fcc = rk818_bat_get_fcc(di);
-+ pre_soc = rk818_bat_get_prev_dsoc(di);
-+ pre_cap = rk818_bat_get_prev_cap(di);
-+ now_cap = rk818_bat_get_coulomb_cap(di);
-+ di->is_halt = is_rk818_bat_last_halt(di);
-+ di->halt_cnt = rk818_bat_get_halt_cnt(di);
-+ di->is_initialized = is_rk818_bat_initialized(di);
-+ di->is_ocv_calib = is_rk818_bat_ocv_valid(di);
-+
-+ if (di->is_initialized) {
-+ BAT_INFO("initialized yet..\n");
-+ goto finish;
-+ } else if (di->is_halt) {
-+ BAT_INFO("system halt last time... cap: pre=%d, now=%d\n",
-+ pre_cap, now_cap);
-+ if (now_cap < 0)
-+ now_cap = 0;
-+ rk818_bat_init_coulomb_cap(di, now_cap);
-+ pre_cap = now_cap;
-+ pre_soc = di->rsoc;
-+ goto finish;
-+ } else if (di->is_ocv_calib) {
-+ ocv_vol = rk818_bat_get_ocv_voltage(di);
-+ ocv_soc = rk818_bat_vol_to_ocvsoc(di, ocv_vol);
-+ ocv_cap = rk818_bat_vol_to_ocvcap(di, ocv_vol);
-+ pre_cap = ocv_cap;
-+ di->ocv_pre_dsoc = pre_soc;
-+ di->ocv_new_dsoc = ocv_soc;
-+ if (abs(ocv_soc - pre_soc) >= di->pdata->max_soc_offset) {
-+ di->ocv_pre_dsoc = pre_soc;
-+ di->ocv_new_dsoc = ocv_soc;
-+ di->is_max_soc_offset = true;
-+ BAT_INFO("trigger max soc offset, dsoc: %d -> %d\n",
-+ pre_soc, ocv_soc);
-+ pre_soc = ocv_soc;
-+ }
-+ BAT_INFO("OCV calib: cap=%d, rsoc=%d\n", ocv_cap, ocv_soc);
-+ } else if (di->pwroff_min > 0) {
-+ ocv_vol = rk818_bat_get_ocv_voltage(di);
-+ ocv_soc = rk818_bat_vol_to_ocvsoc(di, ocv_vol);
-+ ocv_cap = rk818_bat_vol_to_ocvcap(di, ocv_vol);
-+ di->force_pre_dsoc = pre_soc;
-+ di->force_new_dsoc = ocv_soc;
-+ if (abs(ocv_soc - pre_soc) >= 80) {
-+ di->is_force_calib = true;
-+ BAT_INFO("dsoc force calib: %d -> %d\n",
-+ pre_soc, ocv_soc);
-+ pre_soc = ocv_soc;
-+ pre_cap = ocv_cap;
-+ }
-+ }
-+
-+finish:
-+ di->dsoc = pre_soc;
-+ di->nac = pre_cap;
-+ if (di->nac < 0)
-+ di->nac = 0;
-+
-+ BAT_INFO("dsoc=%d cap=%d v=%d ov=%d rv=%d min=%d psoc=%d pcap=%d\n",
-+ di->dsoc, di->nac, rk818_bat_get_avg_voltage(di),
-+ rk818_bat_get_ocv_voltage(di), rk818_bat_get_relax_voltage(di),
-+ di->pwroff_min, rk818_bat_get_prev_dsoc(di),
-+ rk818_bat_get_prev_cap(di));
-+}
-+
-+static bool rk818_bat_ocv_sw_reset(struct rk818_battery *di)
-+{
-+ u8 buf;
-+
-+ buf = rk818_bat_read(di, RK818_MISC_MARK_REG);
-+ if (((buf & FG_RESET_LATE) && di->pwroff_min >= 30) ||
-+ (buf & FG_RESET_NOW)) {
-+ buf &= ~FG_RESET_LATE;
-+ buf &= ~FG_RESET_NOW;
-+ rk818_bat_write(di, RK818_MISC_MARK_REG, buf);
-+ BAT_INFO("manual reset fuel gauge\n");
-+ return true;
-+ } else {
-+ return false;
-+ }
-+}
-+
-+static void rk818_bat_init_rsoc(struct rk818_battery *di)
-+{
-+ di->is_first_power_on = is_rk818_bat_first_pwron(di);
-+ di->is_sw_reset = rk818_bat_ocv_sw_reset(di);
-+ di->pwroff_min = rk818_bat_get_pwroff_min(di);
-+
-+ if (di->is_first_power_on || di->is_sw_reset)
-+ rk818_bat_first_pwron(di);
-+ else
-+ rk818_bat_not_first_pwron(di);
-+}
-+
-+static u8 rk818_bat_get_chrg_status(struct rk818_battery *di)
-+{
-+ u8 status;
-+
-+ status = rk818_bat_read(di, RK818_SUP_STS_REG) & CHRG_STATUS_MSK;
-+ switch (status) {
-+ case CHARGE_OFF:
-+ DBG("CHARGE-OFF ...\n");
-+ break;
-+ case DEAD_CHARGE:
-+ BAT_INFO("DEAD CHARGE...\n");
-+ break;
-+ case TRICKLE_CHARGE:
-+ BAT_INFO("TRICKLE CHARGE...\n ");
-+ break;
-+ case CC_OR_CV:
-+ DBG("CC or CV...\n");
-+ break;
-+ case CHARGE_FINISH:
-+ DBG("CHARGE FINISH...\n");
-+ break;
-+ case USB_OVER_VOL:
-+ BAT_INFO("USB OVER VOL...\n");
-+ break;
-+ case BAT_TMP_ERR:
-+ BAT_INFO("BAT TMP ERROR...\n");
-+ break;
-+ case TIMER_ERR:
-+ BAT_INFO("TIMER ERROR...\n");
-+ break;
-+ case USB_EXIST:
-+ BAT_INFO("USB EXIST...\n");
-+ break;
-+ case USB_EFF:
-+ BAT_INFO("USB EFF...\n");
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return status;
-+}
-+
-+static u8 rk818_bat_parse_fb_temperature(struct rk818_battery *di)
-+{
-+ u8 reg;
-+ int index, fb_temp;
-+
-+ reg = DEFAULT_FB_TEMP;
-+ fb_temp = di->pdata->fb_temp;
-+ for (index = 0; index < ARRAY_SIZE(feedback_temp_array); index++) {
-+ if (fb_temp < feedback_temp_array[index])
-+ break;
-+ reg = (index << FB_TEMP_SHIFT);
-+ }
-+
-+ return reg;
-+}
-+
-+static u8 rk818_bat_parse_finish_ma(struct rk818_battery *di, int fcc)
-+{
-+ u8 ma;
-+
-+ if (di->pdata->sample_res == SAMPLE_RES_10MR)
-+ ma = FINISH_100MA;
-+ else if (fcc > 5000)
-+ ma = FINISH_250MA;
-+ else if (fcc >= 4000)
-+ ma = FINISH_200MA;
-+ else if (fcc >= 3000)
-+ ma = FINISH_150MA;
-+ else
-+ ma = FINISH_100MA;
-+
-+ return ma;
-+}
-+
-+static void rk818_bat_init_chrg_config(struct rk818_battery *di)
-+{
-+ u8 usb_ctrl, chrg_ctrl2, chrg_ctrl3;
-+ u8 thermal, ggcon, finish_ma, fb_temp;
-+
-+ finish_ma = rk818_bat_parse_finish_ma(di, di->fcc);
-+ fb_temp = rk818_bat_parse_fb_temperature(di);
-+
-+ ggcon = rk818_bat_read(di, RK818_GGCON_REG);
-+ thermal = rk818_bat_read(di, RK818_THERMAL_REG);
-+ usb_ctrl = rk818_bat_read(di, RK818_USB_CTRL_REG);
-+ chrg_ctrl2 = rk818_bat_read(di, RK818_CHRG_CTRL_REG2);
-+ chrg_ctrl3 = rk818_bat_read(di, RK818_CHRG_CTRL_REG3);
-+
-+ /* set charge finish current */
-+ chrg_ctrl3 |= CHRG_TERM_DIG_SIGNAL;
-+ chrg_ctrl2 &= ~FINISH_CUR_MSK;
-+ chrg_ctrl2 |= finish_ma;
-+
-+ /* disable cccv mode */
-+ chrg_ctrl3 &= ~CHRG_TIMER_CCCV_EN;
-+
-+ /* set feed back temperature */
-+ if (di->pdata->fb_temp)
-+ usb_ctrl |= CHRG_CT_EN;
-+ else
-+ usb_ctrl &= ~CHRG_CT_EN;
-+ thermal &= ~FB_TEMP_MSK;
-+ thermal |= fb_temp;
-+
-+ /* adc current mode */
-+ ggcon |= ADC_CUR_MODE;
-+
-+ rk818_bat_write(di, RK818_GGCON_REG, ggcon);
-+ rk818_bat_write(di, RK818_THERMAL_REG, thermal);
-+ rk818_bat_write(di, RK818_USB_CTRL_REG, usb_ctrl);
-+ rk818_bat_write(di, RK818_CHRG_CTRL_REG2, chrg_ctrl2);
-+ rk818_bat_write(di, RK818_CHRG_CTRL_REG3, chrg_ctrl3);
-+}
-+
-+static void rk818_bat_init_coffset(struct rk818_battery *di)
-+{
-+ int coffset, ioffset;
-+
-+ ioffset = rk818_bat_get_ioffset(di);
-+ di->poffset = rk818_bat_read(di, RK818_POFFSET_REG);
-+ if (!di->poffset)
-+ di->poffset = DEFAULT_POFFSET;
-+
-+ coffset = di->poffset + ioffset;
-+ if (coffset < INVALID_COFFSET_MIN || coffset > INVALID_COFFSET_MAX)
-+ coffset = DEFAULT_COFFSET;
-+
-+ rk818_bat_set_coffset(di, coffset);
-+
-+ DBG("<%s>. offset: p=0x%x, i=0x%x, c=0x%x\n",
-+ __func__, di->poffset, ioffset, rk818_bat_get_coffset(di));
-+}
-+
-+static void rk818_bat_caltimer_isr(struct timer_list *t)
-+{
-+ struct rk818_battery *di = from_timer(di, t, caltimer);
-+
-+ mod_timer(&di->caltimer, jiffies + MINUTE(8) * HZ);
-+ queue_delayed_work(di->bat_monitor_wq, &di->calib_delay_work,
-+ msecs_to_jiffies(10));
-+}
-+
-+static void rk818_bat_internal_calib(struct work_struct *work)
-+{
-+ int ioffset, poffset;
-+ struct rk818_battery *di = container_of(work,
-+ struct rk818_battery, calib_delay_work.work);
-+
-+ /* calib coffset */
-+ poffset = rk818_bat_read(di, RK818_POFFSET_REG);
-+ if (poffset)
-+ di->poffset = poffset;
-+ else
-+ di->poffset = DEFAULT_POFFSET;
-+
-+ ioffset = rk818_bat_get_ioffset(di);
-+ rk818_bat_set_coffset(di, ioffset + di->poffset);
-+
-+ /* calib voltage kb */
-+ rk818_bat_init_voltage_kb(di);
-+ BAT_INFO("caltimer: ioffset=0x%x, coffset=0x%x, poffset=%d\n",
-+ ioffset, rk818_bat_get_coffset(di), di->poffset);
-+}
-+
-+static void rk818_bat_init_caltimer(struct rk818_battery *di)
-+{
-+ timer_setup(&di->caltimer, rk818_bat_caltimer_isr, 0);
-+ di->caltimer.expires = jiffies + MINUTE(8) * HZ;
-+ add_timer(&di->caltimer);
-+ INIT_DELAYED_WORK(&di->calib_delay_work, rk818_bat_internal_calib);
-+}
-+
-+static void rk818_bat_init_zero_table(struct rk818_battery *di)
-+{
-+ int i, diff, min, max;
-+ size_t ocv_size, length;
-+
-+ ocv_size = di->pdata->ocv_size;
-+ length = sizeof(di->pdata->zero_table) * ocv_size;
-+ di->pdata->zero_table =
-+ devm_kzalloc(di->dev, length, GFP_KERNEL);
-+ if (!di->pdata->zero_table) {
-+ di->pdata->zero_table = di->pdata->ocv_table;
-+ dev_err(di->dev, "malloc zero table fail\n");
-+ return;
-+ }
-+
-+ min = di->pdata->pwroff_vol,
-+ max = di->pdata->ocv_table[ocv_size - 4];
-+ diff = (max - min) / DIV(ocv_size - 1);
-+ for (i = 0; i < ocv_size; i++)
-+ di->pdata->zero_table[i] = min + (i * diff);
-+
-+ for (i = 0; i < ocv_size; i++)
-+ DBG("zero[%d] = %d\n", i, di->pdata->zero_table[i]);
-+
-+ for (i = 0; i < ocv_size; i++)
-+ DBG("ocv[%d] = %d\n", i, di->pdata->ocv_table[i]);
-+}
-+
-+static void rk818_bat_calc_sm_linek(struct rk818_battery *di)
-+{
-+ int linek, current_avg;
-+ u8 diff, delta;
-+
-+ delta = abs(di->dsoc - di->rsoc);
-+ diff = delta * 3;/* speed:3/4 */
-+ current_avg = rk818_bat_get_avg_current(di);
-+ if (current_avg >= 0) {
-+ if (di->dsoc < di->rsoc)
-+ linek = 1000 * (delta + diff) / DIV(diff);
-+ else if (di->dsoc > di->rsoc)
-+ linek = 1000 * diff / DIV(delta + diff);
-+ else
-+ linek = 1000;
-+ di->dbg_meet_soc = (di->dsoc >= di->rsoc) ?
-+ (di->dsoc + diff) : (di->rsoc + diff);
-+ } else {
-+ if (di->dsoc < di->rsoc)
-+ linek = -1000 * diff / DIV(delta + diff);
-+ else if (di->dsoc > di->rsoc)
-+ linek = -1000 * (delta + diff) / DIV(diff);
-+ else
-+ linek = -1000;
-+ di->dbg_meet_soc = (di->dsoc >= di->rsoc) ?
-+ (di->dsoc - diff) : (di->rsoc - diff);
-+ }
-+
-+ di->sm_linek = linek;
-+ di->sm_remain_cap = di->remain_cap;
-+ di->dbg_calc_dsoc = di->dsoc;
-+ di->dbg_calc_rsoc = di->rsoc;
-+
-+ DBG("<%s>.diff=%d, k=%d, cur=%d\n", __func__, diff, linek, current_avg);
-+}
-+
-+static void rk818_bat_calc_zero_linek(struct rk818_battery *di)
-+{
-+ int dead_voltage, ocv_voltage;
-+ int voltage_avg, current_avg, vsys;
-+ int ocv_cap, dead_cap, xsoc;
-+ int ocv_soc, dead_soc;
-+ int pwroff_vol;
-+ int i, cnt, vol_old, vol_now;
-+ int org_linek = 0, min_gap_xsoc;
-+
-+ if ((abs(di->current_avg) < 500) && (di->dsoc > 10))
-+ pwroff_vol = di->pdata->pwroff_vol + 50;
-+ else
-+ pwroff_vol = di->pdata->pwroff_vol;
-+
-+ do {
-+ vol_old = rk818_bat_get_avg_voltage(di);
-+ msleep(100);
-+ vol_now = rk818_bat_get_avg_voltage(di);
-+ cnt++;
-+ } while ((vol_old == vol_now) && (cnt < 11));
-+
-+ voltage_avg = 0;
-+ for (i = 0; i < 10; i++) {
-+ voltage_avg += rk818_bat_get_avg_voltage(di);
-+ msleep(100);
-+ }
-+
-+ /* calc estimate ocv voltage */
-+ voltage_avg /= 10;
-+ current_avg = rk818_bat_get_avg_current(di);
-+ vsys = voltage_avg + (current_avg * DEF_PWRPATH_RES) / 1000;
-+
-+ DBG("ZERO0: shtd_vol: org = %d, now = %d, zero_reserve_dsoc = %d\n",
-+ di->pdata->pwroff_vol, pwroff_vol, di->pdata->zero_reserve_dsoc);
-+
-+ dead_voltage = pwroff_vol - current_avg *
-+ (di->bat_res + DEF_PWRPATH_RES) / 1000;
-+ ocv_voltage = voltage_avg - (current_avg * di->bat_res) / 1000;
-+ DBG("ZERO0: dead_voltage(shtd) = %d, ocv_voltage(now) = %d\n",
-+ dead_voltage, ocv_voltage);
-+
-+ /* calc estimate soc and cap */
-+ dead_soc = rk818_bat_vol_to_zerosoc(di, dead_voltage);
-+ dead_cap = rk818_bat_vol_to_zerocap(di, dead_voltage);
-+ DBG("ZERO0: dead_soc = %d, dead_cap = %d\n",
-+ dead_soc, dead_cap);
-+
-+ ocv_soc = rk818_bat_vol_to_zerosoc(di, ocv_voltage);
-+ ocv_cap = rk818_bat_vol_to_zerocap(di, ocv_voltage);
-+ DBG("ZERO0: ocv_soc = %d, ocv_cap = %d\n",
-+ ocv_soc, ocv_cap);
-+
-+ /* xsoc: available rsoc */
-+ xsoc = ocv_soc - dead_soc;
-+
-+ /* min_gap_xsoc: reserve xsoc */
-+ if (abs(current_avg) > ZERO_LOAD_LVL1)
-+ min_gap_xsoc = ZERO_GAP_XSOC3;
-+ else if (abs(current_avg) > ZERO_LOAD_LVL2)
-+ min_gap_xsoc = ZERO_GAP_XSOC2;
-+ else
-+ min_gap_xsoc = ZERO_GAP_XSOC1;
-+
-+ if ((xsoc <= 30) && (di->dsoc >= di->pdata->zero_reserve_dsoc))
-+ min_gap_xsoc = min_gap_xsoc + ZERO_GAP_CALIB;
-+
-+ di->zero_remain_cap = di->remain_cap;
-+ di->zero_timeout_cnt = 0;
-+ if ((di->dsoc <= 1) && (xsoc > 0)) {
-+ di->zero_linek = 400;
-+ di->zero_drop_sec = 0;
-+ } else if (xsoc >= 0) {
-+ di->zero_drop_sec = 0;
-+ di->zero_linek = (di->zero_dsoc + xsoc / 2) / DIV(xsoc);
-+ org_linek = di->zero_linek;
-+ /* battery energy mode to use up voltage */
-+ if ((di->pdata->energy_mode) &&
-+ (xsoc - di->dsoc >= ZERO_GAP_XSOC3) &&
-+ (di->dsoc <= 10) && (di->zero_linek < 300)) {
-+ di->zero_linek = 300;
-+ DBG("ZERO-new: zero_linek adjust step0...\n");
-+ /* reserve enough power yet, slow down any way */
-+ } else if ((xsoc - di->dsoc >= min_gap_xsoc) ||
-+ ((xsoc - di->dsoc >= ZERO_GAP_XSOC2) &&
-+ (di->dsoc <= 10) && (xsoc > 15))) {
-+ if (xsoc <= 20 &&
-+ di->dsoc >= di->pdata->zero_reserve_dsoc)
-+ di->zero_linek = 1200;
-+ else if (xsoc - di->dsoc >= 2 * min_gap_xsoc)
-+ di->zero_linek = 400;
-+ else if (xsoc - di->dsoc >= 3 + min_gap_xsoc)
-+ di->zero_linek = 600;
-+ else
-+ di->zero_linek = 800;
-+ DBG("ZERO-new: zero_linek adjust step1...\n");
-+ /* control zero mode beginning enter */
-+ } else if ((di->zero_linek > 1800) && (di->dsoc > 70)) {
-+ di->zero_linek = 1800;
-+ DBG("ZERO-new: zero_linek adjust step2...\n");
-+ /* dsoc close to xsoc: it must reserve power */
-+ } else if ((di->zero_linek > 1000) && (di->zero_linek < 1200)) {
-+ di->zero_linek = 1200;
-+ DBG("ZERO-new: zero_linek adjust step3...\n");
-+ /* dsoc[5~15], dsoc < xsoc */
-+ } else if ((di->dsoc <= 15 && di->dsoc > 5) &&
-+ (di->zero_linek <= 1200)) {
-+ /* slow down */
-+ if (xsoc - di->dsoc >= min_gap_xsoc)
-+ di->zero_linek = 800;
-+ /* reserve power */
-+ else
-+ di->zero_linek = 1200;
-+ DBG("ZERO-new: zero_linek adjust step4...\n");
-+ /* dsoc[5, 100], dsoc < xsoc */
-+ } else if ((di->zero_linek < 1000) && (di->dsoc >= 5)) {
-+ if ((xsoc - di->dsoc) < min_gap_xsoc) {
-+ /* reserve power */
-+ di->zero_linek = 1200;
-+ } else {
-+ if (abs(di->current_avg) > 500)/* heavy */
-+ di->zero_linek = 900;
-+ else
-+ di->zero_linek = 1000;
-+ }
-+ DBG("ZERO-new: zero_linek adjust step5...\n");
-+ /* dsoc[0~5], dsoc < xsoc */
-+ } else if ((di->zero_linek < 1000) && (di->dsoc <= 5)) {
-+ if ((xsoc - di->dsoc) <= 3)
-+ di->zero_linek = 1200;
-+ else
-+ di->zero_linek = 800;
-+ DBG("ZERO-new: zero_linek adjust step6...\n");
-+ }
-+ } else {
-+ /* xsoc < 0 */
-+ di->zero_linek = 1000;
-+ if (!di->zero_drop_sec)
-+ di->zero_drop_sec = get_boot_sec();
-+ if (base2sec(di->zero_drop_sec) >= WAIT_DSOC_DROP_SEC) {
-+ DBG("ZERO0: t=%lu\n", base2sec(di->zero_drop_sec));
-+ di->zero_drop_sec = 0;
-+ di->dsoc--;
-+ di->zero_dsoc = (di->dsoc + 1) * 1000 -
-+ MIN_ACCURACY;
-+ }
-+ }
-+
-+ if (voltage_avg < pwroff_vol - 70) {
-+ if (!di->shtd_drop_sec)
-+ di->shtd_drop_sec = get_boot_sec();
-+ if (base2sec(di->shtd_drop_sec) > WAIT_SHTD_DROP_SEC) {
-+ BAT_INFO("voltage extreme low...soc:%d->0\n", di->dsoc);
-+ di->shtd_drop_sec = 0;
-+ di->dsoc = 0;
-+ }
-+ } else {
-+ di->shtd_drop_sec = 0;
-+ }
-+
-+ DBG("ZERO-new: org_linek=%d, zero_linek=%d, dsoc=%d, Xsoc=%d, "
-+ "rsoc=%d, gap=%d, v=%d, vsys=%d\n"
-+ "ZERO-new: di->zero_dsoc=%d, zero_remain_cap=%d, zero_drop=%ld, "
-+ "sht_drop=%ld\n\n",
-+ org_linek, di->zero_linek, di->dsoc, xsoc, di->rsoc,
-+ min_gap_xsoc, voltage_avg, vsys, di->zero_dsoc, di->zero_remain_cap,
-+ base2sec(di->zero_drop_sec), base2sec(di->shtd_drop_sec));
-+}
-+
-+static void rk818_bat_finish_algo_prepare(struct rk818_battery *di)
-+{
-+ di->finish_base = get_boot_sec();
-+ if (!di->finish_base)
-+ di->finish_base = 1;
-+}
-+
-+static void rk818_bat_smooth_algo_prepare(struct rk818_battery *di)
-+{
-+ int tmp_soc;
-+
-+ tmp_soc = di->sm_chrg_dsoc / 1000;
-+ if (tmp_soc != di->dsoc)
-+ di->sm_chrg_dsoc = di->dsoc * 1000;
-+
-+ tmp_soc = di->sm_dischrg_dsoc / 1000;
-+ if (tmp_soc != di->dsoc)
-+ di->sm_dischrg_dsoc =
-+ (di->dsoc + 1) * 1000 - MIN_ACCURACY;
-+
-+ DBG("<%s>. tmp_soc=%d, dsoc=%d, dsoc:sm_dischrg=%d, sm_chrg=%d\n",
-+ __func__, tmp_soc, di->dsoc, di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
-+
-+ rk818_bat_calc_sm_linek(di);
-+}
-+
-+static void rk818_bat_zero_algo_prepare(struct rk818_battery *di)
-+{
-+ int tmp_dsoc;
-+
-+ di->zero_timeout_cnt = 0;
-+ tmp_dsoc = di->zero_dsoc / 1000;
-+ if (tmp_dsoc != di->dsoc)
-+ di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
-+
-+ DBG("<%s>. first calc, reinit linek\n", __func__);
-+
-+ rk818_bat_calc_zero_linek(di);
-+}
-+
-+static void rk818_bat_calc_zero_algorithm(struct rk818_battery *di)
-+{
-+ int tmp_soc = 0, sm_delta_dsoc = 0;
-+
-+ tmp_soc = di->zero_dsoc / 1000;
-+ if (tmp_soc == di->dsoc)
-+ goto out;
-+
-+ DBG("<%s>. enter: dsoc=%d, rsoc=%d\n", __func__, di->dsoc, di->rsoc);
-+ /* when discharge slow down, take sm chrg into calc */
-+ if (di->dsoc < di->rsoc) {
-+ /* take sm charge rest into calc */
-+ tmp_soc = di->sm_chrg_dsoc / 1000;
-+ if (tmp_soc == di->dsoc) {
-+ sm_delta_dsoc = di->sm_chrg_dsoc - di->dsoc * 1000;
-+ di->sm_chrg_dsoc = di->dsoc * 1000;
-+ di->zero_dsoc += sm_delta_dsoc;
-+ DBG("ZERO1: take sm chrg,delta=%d\n", sm_delta_dsoc);
-+ }
-+ }
-+
-+ /* when discharge speed up, take sm dischrg into calc */
-+ if (di->dsoc > di->rsoc) {
-+ /* take sm discharge rest into calc */
-+ tmp_soc = di->sm_dischrg_dsoc / 1000;
-+ if (tmp_soc == di->dsoc) {
-+ sm_delta_dsoc = di->sm_dischrg_dsoc -
-+ ((di->dsoc + 1) * 1000 - MIN_ACCURACY);
-+ di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 -
-+ MIN_ACCURACY;
-+ di->zero_dsoc += sm_delta_dsoc;
-+ DBG("ZERO1: take sm dischrg,delta=%d\n", sm_delta_dsoc);
-+ }
-+ }
-+
-+ /* check overflow */
-+ if (di->zero_dsoc > (di->dsoc + 1) * 1000 - MIN_ACCURACY) {
-+ DBG("ZERO1: zero dsoc overflow: %d\n", di->zero_dsoc);
-+ di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
-+ }
-+
-+ /* check new dsoc */
-+ tmp_soc = di->zero_dsoc / 1000;
-+ if (tmp_soc != di->dsoc) {
-+ /* avoid dsoc jump when heavy load */
-+ if ((di->dsoc - tmp_soc) > 1) {
-+ di->dsoc--;
-+ di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
-+ DBG("ZERO1: heavy load...\n");
-+ } else {
-+ di->dsoc = tmp_soc;
-+ }
-+ di->zero_drop_sec = 0;
-+ }
-+
-+out:
-+ DBG("ZERO1: zero_dsoc(Y0)=%d, dsoc=%d, rsoc=%d, tmp_soc=%d\n",
-+ di->zero_dsoc, di->dsoc, di->rsoc, tmp_soc);
-+ DBG("ZERO1: sm_dischrg_dsoc=%d, sm_chrg_dsoc=%d\n",
-+ di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
-+}
-+
-+static void rk818_bat_zero_algorithm(struct rk818_battery *di)
-+{
-+ int delta_cap = 0, delta_soc = 0;
-+
-+ di->zero_timeout_cnt++;
-+ delta_cap = di->zero_remain_cap - di->remain_cap;
-+ delta_soc = di->zero_linek * (delta_cap * 100) / DIV(di->fcc);
-+
-+ DBG("ZERO1: zero_linek=%d, zero_dsoc(Y0)=%d, dsoc=%d, rsoc=%d\n"
-+ "ZERO1: delta_soc(X0)=%d, delta_cap=%d, zero_remain_cap = %d\n"
-+ "ZERO1: timeout_cnt=%d, sm_dischrg=%d, sm_chrg=%d\n\n",
-+ di->zero_linek, di->zero_dsoc, di->dsoc, di->rsoc,
-+ delta_soc, delta_cap, di->zero_remain_cap,
-+ di->zero_timeout_cnt, di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
-+
-+ if ((delta_soc >= MIN_ZERO_DSOC_ACCURACY) ||
-+ (di->zero_timeout_cnt > MIN_ZERO_OVERCNT) ||
-+ (di->zero_linek == 0)) {
-+ DBG("ZERO1:--------- enter calc -----------\n");
-+ di->zero_timeout_cnt = 0;
-+ di->zero_dsoc -= delta_soc;
-+ rk818_bat_calc_zero_algorithm(di);
-+ rk818_bat_calc_zero_linek(di);
-+ }
-+}
-+
-+static void rk818_bat_dump_time_table(struct rk818_battery *di)
-+{
-+ u8 i;
-+ static int old_index;
-+ static int old_min;
-+ int mod = di->dsoc % 10;
-+ int index = di->dsoc / 10;
-+ u32 time;
-+
-+ if (rk818_bat_chrg_online(di))
-+ time = base2min(di->plug_in_base);
-+ else
-+ time = base2min(di->plug_out_base);
-+
-+ if ((mod == 0) && (index > 0) && (old_index != index)) {
-+ di->dbg_chrg_min[index - 1] = time - old_min;
-+ old_min = time;
-+ old_index = index;
-+ }
-+
-+ for (i = 1; i < 11; i++)
-+ DBG("Time[%d]=%d, ", (i * 10), di->dbg_chrg_min[i - 1]);
-+ DBG("\n");
-+}
-+
-+static void rk818_bat_debug_info(struct rk818_battery *di)
-+{
-+ u8 sup_tst, ggcon, ggsts, vb_mod, ts_ctrl, reboot_cnt;
-+ u8 usb_ctrl, chrg_ctrl1, thermal;
-+ u8 int_sts1, int_sts2;
-+ u8 int_msk1, int_msk2;
-+ u8 chrg_ctrl2, chrg_ctrl3, rtc, misc, dcdc_en;
-+ char *work_mode[] = {"ZERO", "FINISH", "UN", "UN", "SMOOTH"};
-+ char *bat_mode[] = {"BAT", "VIRTUAL"};
-+
-+ if (rk818_bat_chrg_online(di))
-+ di->plug_out_base = get_boot_sec();
-+ else
-+ di->plug_in_base = get_boot_sec();
-+
-+ rk818_bat_dump_time_table(di);
-+
-+ if (!dbg_enable)
-+ return;
-+
-+ ts_ctrl = rk818_bat_read(di, RK818_TS_CTRL_REG);
-+ misc = rk818_bat_read(di, RK818_MISC_MARK_REG);
-+ ggcon = rk818_bat_read(di, RK818_GGCON_REG);
-+ ggsts = rk818_bat_read(di, RK818_GGSTS_REG);
-+ sup_tst = rk818_bat_read(di, RK818_SUP_STS_REG);
-+ vb_mod = rk818_bat_read(di, RK818_VB_MON_REG);
-+ usb_ctrl = rk818_bat_read(di, RK818_USB_CTRL_REG);
-+ chrg_ctrl1 = rk818_bat_read(di, RK818_CHRG_CTRL_REG1);
-+ chrg_ctrl2 = rk818_bat_read(di, RK818_CHRG_CTRL_REG2);
-+ chrg_ctrl3 = rk818_bat_read(di, RK818_CHRG_CTRL_REG3);
-+ rtc = rk818_bat_read(di, 0);
-+ thermal = rk818_bat_read(di, RK818_THERMAL_REG);
-+ int_sts1 = rk818_bat_read(di, RK818_INT_STS_REG1);
-+ int_sts2 = rk818_bat_read(di, RK818_INT_STS_REG2);
-+ int_msk1 = rk818_bat_read(di, RK818_INT_STS_MSK_REG1);
-+ int_msk2 = rk818_bat_read(di, RK818_INT_STS_MSK_REG2);
-+ dcdc_en = rk818_bat_read(di, RK818_DCDC_EN_REG);
-+ reboot_cnt = rk818_bat_read(di, RK818_REBOOT_CNT_REG);
-+
-+ DBG("\n------- DEBUG REGS, [Ver: %s] -------------------\n"
-+ "GGCON=0x%2x, GGSTS=0x%2x, RTC=0x%2x, DCDC_EN2=0x%2x\n"
-+ "SUP_STS= 0x%2x, VB_MOD=0x%2x, USB_CTRL=0x%2x\n"
-+ "THERMAL=0x%2x, MISC_MARK=0x%2x, TS_CTRL=0x%2x\n"
-+ "CHRG_CTRL:REG1=0x%2x, REG2=0x%2x, REG3=0x%2x\n"
-+ "INT_STS: REG1=0x%2x, REG2=0x%2x\n"
-+ "INT_MSK: REG1=0x%2x, REG2=0x%2x\n",
-+ DRIVER_VERSION, ggcon, ggsts, rtc, dcdc_en,
-+ sup_tst, vb_mod, usb_ctrl,
-+ thermal, misc, ts_ctrl,
-+ chrg_ctrl1, chrg_ctrl2, chrg_ctrl3,
-+ int_sts1, int_sts2, int_msk1, int_msk2
-+ );
-+
-+ DBG("###############################################################\n"
-+ "Dsoc=%d, Rsoc=%d, Vavg=%d, Iavg=%d, Cap=%d, Fcc=%d, d=%d\n"
-+ "K=%d, Mode=%s, Oldcap=%d, Is=%d, Ip=%d, Vs=%d\n"
-+ "fb_temp=%d, bat_temp=%d, sample_res=%d, USB=%d, DC=%d\n"
-+ "off:i=0x%x, c=0x%x, p=%d, Rbat=%d, age_ocv_cap=%d, fb=%d, hot=%d\n"
-+ "adp:finish=%lu, boot_min=%lu, sleep_min=%lu, adc=%d, Vsys=%d\n"
-+ "bat:%s, meet: soc=%d, calc: dsoc=%d, rsoc=%d, Vocv=%d\n"
-+ "pwr: dsoc=%d, rsoc=%d, vol=%d, halt: st=%d, cnt=%d, reboot=%d\n"
-+ "ocv_c=%d: %d -> %d; max_c=%d: %d -> %d; force_c=%d: %d -> %d\n"
-+ "min=%d, init=%d, sw=%d, below0=%d, first=%d, changed=%d\n"
-+ "###############################################################\n",
-+ di->dsoc, di->rsoc, di->voltage_avg, di->current_avg,
-+ di->remain_cap, di->fcc, di->rsoc - di->dsoc,
-+ di->sm_linek, work_mode[di->work_mode], di->sm_remain_cap,
-+ di->res_div * chrg_cur_sel_array[chrg_ctrl1 & 0x0f],
-+ chrg_cur_input_array[usb_ctrl & 0x0f],
-+ chrg_vol_sel_array[(chrg_ctrl1 & 0x70) >> 4],
-+ feedback_temp_array[(thermal & 0x0c) >> 2], di->temperature,
-+ di->pdata->sample_res, di->usb_in, di->ac_in,
-+ rk818_bat_get_ioffset(di),
-+ rk818_bat_get_coffset(di), di->poffset, di->bat_res,
-+ di->age_adjust_cap, di->fb_blank, !!(thermal & HOTDIE_STS),
-+ base2min(di->finish_base),
-+ base2min(di->boot_base), di->sleep_sum_sec / 60,
-+ di->adc_allow_update,
-+ di->voltage_avg + di->current_avg * DEF_PWRPATH_RES / 1000,
-+ bat_mode[di->pdata->bat_mode], di->dbg_meet_soc, di->dbg_calc_dsoc,
-+ di->dbg_calc_rsoc, di->voltage_ocv, di->dbg_pwr_dsoc,
-+ di->dbg_pwr_rsoc, di->dbg_pwr_vol, di->is_halt, di->halt_cnt,
-+ reboot_cnt, di->is_ocv_calib, di->ocv_pre_dsoc, di->ocv_new_dsoc,
-+ di->is_max_soc_offset, di->max_pre_dsoc, di->max_new_dsoc,
-+ di->is_force_calib, di->force_pre_dsoc, di->force_new_dsoc,
-+ di->pwroff_min, di->is_initialized, di->is_sw_reset,
-+ di->dbg_cap_low0, di->is_first_on, di->last_dsoc
-+ );
-+}
-+
-+static void rk818_bat_init_capacity(struct rk818_battery *di, u32 cap)
-+{
-+ int delta_cap;
-+
-+ delta_cap = cap - di->remain_cap;
-+ if (!delta_cap)
-+ return;
-+
-+ di->age_adjust_cap += delta_cap;
-+ rk818_bat_init_coulomb_cap(di, cap);
-+ rk818_bat_smooth_algo_prepare(di);
-+ rk818_bat_zero_algo_prepare(di);
-+}
-+
-+static void rk818_bat_update_age_fcc(struct rk818_battery *di)
-+{
-+ int fcc, remain_cap, age_keep_min, lock_fcc;
-+
-+ lock_fcc = rk818_bat_get_coulomb_cap(di);
-+ remain_cap = lock_fcc - di->age_ocv_cap - di->age_adjust_cap;
-+ age_keep_min = base2min(di->age_keep_sec);
-+
-+ DBG("%s: lock_fcc=%d, age_ocv_cap=%d, age_adjust_cap=%d, remain_cap=%d,"
-+ "age_allow_update=%d, age_keep_min=%d\n",
-+ __func__, lock_fcc, di->age_ocv_cap, di->age_adjust_cap, remain_cap,
-+ di->age_allow_update, age_keep_min);
-+
-+ if ((di->chrg_status == CHARGE_FINISH) && (di->age_allow_update) &&
-+ (age_keep_min < 1200)) {
-+ di->age_allow_update = false;
-+ fcc = remain_cap * 100 / DIV(100 - di->age_ocv_soc);
-+ BAT_INFO("lock_fcc=%d, calc_cap=%d, age: soc=%d, cap=%d, "
-+ "level=%d, fcc:%d->%d?\n",
-+ lock_fcc, remain_cap, di->age_ocv_soc,
-+ di->age_ocv_cap, di->age_level, di->fcc, fcc);
-+
-+ if ((fcc < di->qmax) && (fcc > MIN_FCC)) {
-+ BAT_INFO("fcc:%d->%d!\n", di->fcc, fcc);
-+ di->fcc = fcc;
-+ rk818_bat_init_capacity(di, di->fcc);
-+ rk818_bat_save_fcc(di, di->fcc);
-+ rk818_bat_save_age_level(di, di->age_level);
-+ }
-+ }
-+}
-+
-+static void rk818_bat_wait_finish_sig(struct rk818_battery *di)
-+{
-+ int chrg_finish_vol = di->pdata->max_chrg_voltage;
-+
-+ if (!rk818_bat_chrg_online(di))
-+ return;
-+
-+ if ((di->chrg_status == CHARGE_FINISH) && (di->adc_allow_update) &&
-+ (di->voltage_avg > chrg_finish_vol - 150)) {
-+ rk818_bat_update_age_fcc(di);
-+ if (rk818_bat_adc_calib(di))
-+ di->adc_allow_update = false;
-+ }
-+}
-+
-+static void rk818_bat_finish_algorithm(struct rk818_battery *di)
-+{
-+ unsigned long finish_sec, soc_sec;
-+ int plus_soc, finish_current, rest = 0;
-+
-+ /* rsoc */
-+ if ((di->remain_cap != di->fcc) &&
-+ (rk818_bat_get_chrg_status(di) == CHARGE_FINISH)) {
-+ di->age_adjust_cap += (di->fcc - di->remain_cap);
-+ rk818_bat_init_coulomb_cap(di, di->fcc);
-+ }
-+
-+ /* dsoc */
-+ if (di->dsoc < 100) {
-+ if (!di->finish_base)
-+ di->finish_base = get_boot_sec();
-+ finish_current = (di->rsoc - di->dsoc) > FINISH_MAX_SOC_DELAY ?
-+ FINISH_CHRG_CUR2 : FINISH_CHRG_CUR1;
-+ finish_sec = base2sec(di->finish_base);
-+ soc_sec = di->fcc * 3600 / 100 / DIV(finish_current);
-+ plus_soc = finish_sec / DIV(soc_sec);
-+ if (finish_sec > soc_sec) {
-+ rest = finish_sec % soc_sec;
-+ di->dsoc += plus_soc;
-+ di->finish_base = get_boot_sec();
-+ if (di->finish_base > rest)
-+ di->finish_base = get_boot_sec() - rest;
-+ }
-+ DBG("<%s>.CHARGE_FINISH:dsoc<100,dsoc=%d\n"
-+ "soc_time=%lu, sec_finish=%lu, plus_soc=%d, rest=%d\n",
-+ __func__, di->dsoc, soc_sec, finish_sec, plus_soc, rest);
-+ }
-+}
-+
-+static void rk818_bat_calc_smooth_dischrg(struct rk818_battery *di)
-+{
-+ int tmp_soc = 0, sm_delta_dsoc = 0, zero_delta_dsoc = 0;
-+
-+ tmp_soc = di->sm_dischrg_dsoc / 1000;
-+ if (tmp_soc == di->dsoc)
-+ goto out;
-+
-+ DBG("<%s>. enter: dsoc=%d, rsoc=%d\n", __func__, di->dsoc, di->rsoc);
-+ /* when dischrge slow down, take sm charge rest into calc */
-+ if (di->dsoc < di->rsoc) {
-+ tmp_soc = di->sm_chrg_dsoc / 1000;
-+ if (tmp_soc == di->dsoc) {
-+ sm_delta_dsoc = di->sm_chrg_dsoc - di->dsoc * 1000;
-+ di->sm_chrg_dsoc = di->dsoc * 1000;
-+ di->sm_dischrg_dsoc += sm_delta_dsoc;
-+ DBG("<%s>. take sm dischrg, delta=%d\n",
-+ __func__, sm_delta_dsoc);
-+ }
-+ }
-+
-+ /* when discharge speed up, take zero discharge rest into calc */
-+ if (di->dsoc > di->rsoc) {
-+ tmp_soc = di->zero_dsoc / 1000;
-+ if (tmp_soc == di->dsoc) {
-+ zero_delta_dsoc = di->zero_dsoc - ((di->dsoc + 1) *
-+ 1000 - MIN_ACCURACY);
-+ di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
-+ di->sm_dischrg_dsoc += zero_delta_dsoc;
-+ DBG("<%s>. take zero schrg, delta=%d\n",
-+ __func__, zero_delta_dsoc);
-+ }
-+ }
-+
-+ /* check up overflow */
-+ if ((di->sm_dischrg_dsoc) > ((di->dsoc + 1) * 1000 - MIN_ACCURACY)) {
-+ DBG("<%s>. dischrg_dsoc up overflow\n", __func__);
-+ di->sm_dischrg_dsoc = (di->dsoc + 1) *
-+ 1000 - MIN_ACCURACY;
-+ }
-+
-+ /* check new dsoc */
-+ tmp_soc = di->sm_dischrg_dsoc / 1000;
-+ if (tmp_soc != di->dsoc) {
-+ di->dsoc = tmp_soc;
-+ di->sm_chrg_dsoc = di->dsoc * 1000;
-+ }
-+out:
-+ DBG("<%s>. dsoc=%d, rsoc=%d, dsoc:sm_dischrg=%d, sm_chrg=%d, zero=%d\n",
-+ __func__, di->dsoc, di->rsoc, di->sm_dischrg_dsoc, di->sm_chrg_dsoc,
-+ di->zero_dsoc);
-+
-+}
-+
-+static void rk818_bat_calc_smooth_chrg(struct rk818_battery *di)
-+{
-+ int tmp_soc = 0, sm_delta_dsoc = 0, zero_delta_dsoc = 0;
-+
-+ tmp_soc = di->sm_chrg_dsoc / 1000;
-+ if (tmp_soc == di->dsoc)
-+ goto out;
-+
-+ DBG("<%s>. enter: dsoc=%d, rsoc=%d\n", __func__, di->dsoc, di->rsoc);
-+ /* when charge slow down, take zero & sm dischrg into calc */
-+ if (di->dsoc > di->rsoc) {
-+ /* take sm discharge rest into calc */
-+ tmp_soc = di->sm_dischrg_dsoc / 1000;
-+ if (tmp_soc == di->dsoc) {
-+ sm_delta_dsoc = di->sm_dischrg_dsoc -
-+ ((di->dsoc + 1) * 1000 - MIN_ACCURACY);
-+ di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 -
-+ MIN_ACCURACY;
-+ di->sm_chrg_dsoc += sm_delta_dsoc;
-+ DBG("<%s>. take sm dischrg, delta=%d\n",
-+ __func__, sm_delta_dsoc);
-+ }
-+
-+ /* take zero discharge rest into calc */
-+ tmp_soc = di->zero_dsoc / 1000;
-+ if (tmp_soc == di->dsoc) {
-+ zero_delta_dsoc = di->zero_dsoc -
-+ ((di->dsoc + 1) * 1000 - MIN_ACCURACY);
-+ di->zero_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
-+ di->sm_chrg_dsoc += zero_delta_dsoc;
-+ DBG("<%s>. take zero dischrg, delta=%d\n",
-+ __func__, zero_delta_dsoc);
-+ }
-+ }
-+
-+ /* check down overflow */
-+ if (di->sm_chrg_dsoc < di->dsoc * 1000) {
-+ DBG("<%s>. chrg_dsoc down overflow\n", __func__);
-+ di->sm_chrg_dsoc = di->dsoc * 1000;
-+ }
-+
-+ /* check new dsoc */
-+ tmp_soc = di->sm_chrg_dsoc / 1000;
-+ if (tmp_soc != di->dsoc) {
-+ di->dsoc = tmp_soc;
-+ di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
-+ }
-+out:
-+ DBG("<%s>.dsoc=%d, rsoc=%d, dsoc: sm_dischrg=%d, sm_chrg=%d, zero=%d\n",
-+ __func__, di->dsoc, di->rsoc, di->sm_dischrg_dsoc, di->sm_chrg_dsoc,
-+ di->zero_dsoc);
-+}
-+
-+static void rk818_bat_smooth_algorithm(struct rk818_battery *di)
-+{
-+ int ydsoc = 0, delta_cap = 0, old_cap = 0;
-+ unsigned long tgt_sec = 0;
-+
-+ di->remain_cap = rk818_bat_get_coulomb_cap(di);
-+
-+ /* full charge: slow down */
-+ if ((di->dsoc == 99) && (di->chrg_status == CC_OR_CV) &&
-+ (di->current_avg > 0)) {
-+ di->sm_linek = FULL_CHRG_K;
-+ /* terminal charge, slow down */
-+ } else if ((di->current_avg >= TERM_CHRG_CURR) &&
-+ (di->chrg_status == CC_OR_CV) && (di->dsoc >= TERM_CHRG_DSOC)) {
-+ di->sm_linek = TERM_CHRG_K;
-+ DBG("<%s>. terminal mode..\n", __func__);
-+ /* simulate charge, speed up */
-+ } else if ((di->current_avg <= SIMULATE_CHRG_CURR) &&
-+ (di->current_avg > 0) && (di->chrg_status == CC_OR_CV) &&
-+ (di->dsoc < TERM_CHRG_DSOC) &&
-+ ((di->rsoc - di->dsoc) >= SIMULATE_CHRG_INTV)) {
-+ di->sm_linek = SIMULATE_CHRG_K;
-+ DBG("<%s>. simulate mode..\n", __func__);
-+ } else {
-+ /* charge and discharge switch */
-+ if ((di->sm_linek * di->current_avg <= 0) ||
-+ (di->sm_linek == TERM_CHRG_K) ||
-+ (di->sm_linek == FULL_CHRG_K) ||
-+ (di->sm_linek == SIMULATE_CHRG_K)) {
-+ DBG("<%s>. linek mode, retinit sm linek..\n", __func__);
-+ rk818_bat_calc_sm_linek(di);
-+ }
-+ }
-+
-+ old_cap = di->sm_remain_cap;
-+ /*
-+ * when dsoc equal rsoc(not include full, term, simulate case),
-+ * sm_linek should change to -1000/1000 smoothly to avoid dsoc+1/-1
-+ * right away, so change it after flat seconds
-+ */
-+ if ((di->dsoc == di->rsoc) && (abs(di->sm_linek) != 1000) &&
-+ (di->sm_linek != FULL_CHRG_K && di->sm_linek != TERM_CHRG_K &&
-+ di->sm_linek != SIMULATE_CHRG_K)) {
-+ if (!di->flat_match_sec)
-+ di->flat_match_sec = get_boot_sec();
-+ tgt_sec = di->fcc * 3600 / 100 / DIV(abs(di->current_avg)) / 3;
-+ if (base2sec(di->flat_match_sec) >= tgt_sec) {
-+ di->flat_match_sec = 0;
-+ di->sm_linek = (di->current_avg >= 0) ? 1000 : -1000;
-+ }
-+ DBG("<%s>. flat_sec=%ld, tgt_sec=%ld, sm_k=%d\n", __func__,
-+ base2sec(di->flat_match_sec), tgt_sec, di->sm_linek);
-+ } else {
-+ di->flat_match_sec = 0;
-+ }
-+
-+ /* abs(k)=1000 or dsoc=100, stop calc */
-+ if ((abs(di->sm_linek) == 1000) || (di->current_avg >= 0 &&
-+ di->chrg_status == CC_OR_CV && di->dsoc >= 100)) {
-+ DBG("<%s>. sm_linek=%d\n", __func__, di->sm_linek);
-+ if (abs(di->sm_linek) == 1000) {
-+ di->dsoc = di->rsoc;
-+ di->sm_linek = (di->sm_linek > 0) ? 1000 : -1000;
-+ DBG("<%s>. dsoc == rsoc, sm_linek=%d\n",
-+ __func__, di->sm_linek);
-+ }
-+ di->sm_remain_cap = di->remain_cap;
-+ di->sm_chrg_dsoc = di->dsoc * 1000;
-+ di->sm_dischrg_dsoc = (di->dsoc + 1) * 1000 - MIN_ACCURACY;
-+ DBG("<%s>. sm_dischrg_dsoc=%d, sm_chrg_dsoc=%d\n",
-+ __func__, di->sm_dischrg_dsoc, di->sm_chrg_dsoc);
-+ } else {
-+ delta_cap = di->remain_cap - di->sm_remain_cap;
-+ if (delta_cap == 0) {
-+ DBG("<%s>. delta_cap = 0\n", __func__);
-+ return;
-+ }
-+ ydsoc = di->sm_linek * abs(delta_cap) * 100 / DIV(di->fcc);
-+ if (ydsoc == 0) {
-+ DBG("<%s>. ydsoc = 0\n", __func__);
-+ return;
-+ }
-+ di->sm_remain_cap = di->remain_cap;
-+
-+ DBG("<%s>. k=%d, ydsoc=%d; cap:old=%d, new:%d; delta_cap=%d\n",
-+ __func__, di->sm_linek, ydsoc, old_cap,
-+ di->sm_remain_cap, delta_cap);
-+
-+ /* discharge mode */
-+ if (ydsoc < 0) {
-+ di->sm_dischrg_dsoc += ydsoc;
-+ rk818_bat_calc_smooth_dischrg(di);
-+ /* charge mode */
-+ } else {
-+ di->sm_chrg_dsoc += ydsoc;
-+ rk818_bat_calc_smooth_chrg(di);
-+ }
-+
-+ if (di->s2r) {
-+ di->s2r = false;
-+ rk818_bat_calc_sm_linek(di);
-+ }
-+ }
-+}
-+
-+/*
-+ * cccv and finish switch all the time will cause dsoc freeze,
-+ * if so, do finish chrg, 100ma is less than min finish_ma.
-+ */
-+static bool rk818_bat_fake_finish_mode(struct rk818_battery *di)
-+{
-+ if ((di->rsoc == 100) && (rk818_bat_get_chrg_status(di) == CC_OR_CV) &&
-+ (abs(di->current_avg) <= 100))
-+ return true;
-+ else
-+ return false;
-+}
-+
-+static void rk818_bat_display_smooth(struct rk818_battery *di)
-+{
-+ /* discharge: reinit "zero & smooth" algorithm to avoid handling dsoc */
-+ if (di->s2r && !di->sleep_chrg_online) {
-+ DBG("s2r: discharge, reset algorithm...\n");
-+ di->s2r = false;
-+ rk818_bat_zero_algo_prepare(di);
-+ rk818_bat_smooth_algo_prepare(di);
-+ return;
-+ }
-+
-+ if (di->work_mode == MODE_FINISH) {
-+ DBG("step1: charge finish...\n");
-+ rk818_bat_finish_algorithm(di);
-+ if ((rk818_bat_get_chrg_status(di) != CHARGE_FINISH) &&
-+ !rk818_bat_fake_finish_mode(di)) {
-+ if ((di->current_avg < 0) &&
-+ (di->voltage_avg < di->pdata->zero_algorithm_vol)) {
-+ DBG("step1: change to zero mode...\n");
-+ rk818_bat_zero_algo_prepare(di);
-+ di->work_mode = MODE_ZERO;
-+ } else {
-+ DBG("step1: change to smooth mode...\n");
-+ rk818_bat_smooth_algo_prepare(di);
-+ di->work_mode = MODE_SMOOTH;
-+ }
-+ }
-+ } else if (di->work_mode == MODE_ZERO) {
-+ DBG("step2: zero algorithm...\n");
-+ rk818_bat_zero_algorithm(di);
-+ if ((di->voltage_avg >= di->pdata->zero_algorithm_vol + 50) ||
-+ (di->current_avg >= 0)) {
-+ DBG("step2: change to smooth mode...\n");
-+ rk818_bat_smooth_algo_prepare(di);
-+ di->work_mode = MODE_SMOOTH;
-+ } else if ((rk818_bat_get_chrg_status(di) == CHARGE_FINISH) ||
-+ rk818_bat_fake_finish_mode(di)) {
-+ DBG("step2: change to finish mode...\n");
-+ rk818_bat_finish_algo_prepare(di);
-+ di->work_mode = MODE_FINISH;
-+ }
-+ } else {
-+ DBG("step3: smooth algorithm...\n");
-+ rk818_bat_smooth_algorithm(di);
-+ if ((di->current_avg < 0) &&
-+ (di->voltage_avg < di->pdata->zero_algorithm_vol)) {
-+ DBG("step3: change to zero mode...\n");
-+ rk818_bat_zero_algo_prepare(di);
-+ di->work_mode = MODE_ZERO;
-+ } else if ((rk818_bat_get_chrg_status(di) == CHARGE_FINISH) ||
-+ rk818_bat_fake_finish_mode(di)) {
-+ DBG("step3: change to finish mode...\n");
-+ rk818_bat_finish_algo_prepare(di);
-+ di->work_mode = MODE_FINISH;
-+ }
-+ }
-+}
-+
-+static void rk818_bat_relax_vol_calib(struct rk818_battery *di)
-+{
-+ int soc, cap, vol;
-+
-+ vol = di->voltage_relax;
-+ soc = rk818_bat_vol_to_ocvsoc(di, vol);
-+ cap = rk818_bat_vol_to_ocvcap(di, vol);
-+ rk818_bat_init_capacity(di, cap);
-+ BAT_INFO("sleep ocv calib: rsoc=%d, cap=%d\n", soc, cap);
-+}
-+
-+static void rk818_bat_relife_age_flag(struct rk818_battery *di)
-+{
-+ u8 ocv_soc, ocv_cap, soc_level;
-+
-+ if (di->voltage_relax <= 0)
-+ return;
-+
-+ ocv_soc = rk818_bat_vol_to_ocvsoc(di, di->voltage_relax);
-+ ocv_cap = rk818_bat_vol_to_ocvcap(di, di->voltage_relax);
-+ DBG("<%s>. ocv_soc=%d, min=%lu, vol=%d\n", __func__,
-+ ocv_soc, di->sleep_dischrg_sec / 60, di->voltage_relax);
-+
-+ /* sleep enough time and ocv_soc enough low */
-+ if (!di->age_allow_update && ocv_soc <= 10) {
-+ di->age_voltage = di->voltage_relax;
-+ di->age_ocv_cap = ocv_cap;
-+ di->age_ocv_soc = ocv_soc;
-+ di->age_adjust_cap = 0;
-+
-+ if (ocv_soc <= 1)
-+ di->age_level = 100;
-+ else if (ocv_soc < 5)
-+ di->age_level = 90;
-+ else
-+ di->age_level = 80;
-+
-+ soc_level = rk818_bat_get_age_level(di);
-+ if (soc_level > di->age_level) {
-+ di->age_allow_update = false;
-+ } else {
-+ di->age_allow_update = true;
-+ di->age_keep_sec = get_boot_sec();
-+ }
-+
-+ BAT_INFO("resume: age_vol:%d, age_ocv_cap:%d, age_ocv_soc:%d, "
-+ "soc_level:%d, age_allow_update:%d, "
-+ "age_level:%d\n",
-+ di->age_voltage, di->age_ocv_cap, ocv_soc, soc_level,
-+ di->age_allow_update, di->age_level);
-+ }
-+}
-+
-+static int rk818_bat_sleep_dischrg(struct rk818_battery *di)
-+{
-+ bool ocv_soc_updated = false;
-+ int tgt_dsoc, gap_soc, sleep_soc = 0;
-+ int pwroff_vol = di->pdata->pwroff_vol;
-+ unsigned long sleep_sec = di->sleep_dischrg_sec;
-+
-+ DBG("<%s>. enter: dsoc=%d, rsoc=%d, rv=%d, v=%d, sleep_min=%lu\n",
-+ __func__, di->dsoc, di->rsoc, di->voltage_relax,
-+ di->voltage_avg, sleep_sec / 60);
-+
-+ if (di->voltage_relax >= di->voltage_avg) {
-+ rk818_bat_relax_vol_calib(di);
-+ rk818_bat_restart_relax(di);
-+ rk818_bat_relife_age_flag(di);
-+ ocv_soc_updated = true;
-+ }
-+
-+ /* handle dsoc */
-+ if (di->dsoc <= di->rsoc) {
-+ di->sleep_sum_cap = (SLP_CURR_MIN * sleep_sec / 3600);
-+ sleep_soc = di->sleep_sum_cap * 100 / DIV(di->fcc);
-+ tgt_dsoc = di->dsoc - sleep_soc;
-+ if (sleep_soc > 0) {
-+ BAT_INFO("calib0: rl=%d, dl=%d, intval=%d\n",
-+ di->rsoc, di->dsoc, sleep_soc);
-+ if (di->dsoc < 5) {
-+ di->dsoc--;
-+ } else if ((tgt_dsoc < 5) && (di->dsoc >= 5)) {
-+ if (di->dsoc == 5)
-+ di->dsoc--;
-+ else
-+ di->dsoc = 5;
-+ } else if (tgt_dsoc > 5) {
-+ di->dsoc = tgt_dsoc;
-+ }
-+ }
-+
-+ DBG("%s: dsoc<=rsoc, sum_cap=%d==>sleep_soc=%d, tgt_dsoc=%d\n",
-+ __func__, di->sleep_sum_cap, sleep_soc, tgt_dsoc);
-+ } else {
-+ /* di->dsoc > di->rsoc */
-+ di->sleep_sum_cap = (SLP_CURR_MAX * sleep_sec / 3600);
-+ sleep_soc = di->sleep_sum_cap / DIV(di->fcc / 100);
-+ gap_soc = di->dsoc - di->rsoc;
-+
-+ BAT_INFO("calib1: rsoc=%d, dsoc=%d, intval=%d\n",
-+ di->rsoc, di->dsoc, sleep_soc);
-+ if (gap_soc > sleep_soc) {
-+ if ((gap_soc - 5) > (sleep_soc * 2))
-+ di->dsoc -= (sleep_soc * 2);
-+ else
-+ di->dsoc -= sleep_soc;
-+ } else {
-+ di->dsoc = di->rsoc;
-+ }
-+
-+ DBG("%s: dsoc>rsoc, sum_cap=%d=>sleep_soc=%d, gap_soc=%d\n",
-+ __func__, di->sleep_sum_cap, sleep_soc, gap_soc);
-+ }
-+
-+ if (di->voltage_avg <= pwroff_vol - 70) {
-+ di->dsoc = 0;
-+ rk_send_wakeup_key();
-+ BAT_INFO("low power sleeping, shutdown... %d\n", di->dsoc);
-+ }
-+
-+ if (ocv_soc_updated && sleep_soc && (di->rsoc - di->dsoc) < 5 &&
-+ di->dsoc < 40) {
-+ di->dsoc--;
-+ BAT_INFO("low power sleeping, reserved... %d\n", di->dsoc);
-+ }
-+
-+ if (di->dsoc <= 0) {
-+ di->dsoc = 0;
-+ rk_send_wakeup_key();
-+ BAT_INFO("sleep dsoc is %d...\n", di->dsoc);
-+ }
-+
-+ DBG("<%s>. out: dsoc=%d, rsoc=%d, sum_cap=%d\n",
-+ __func__, di->dsoc, di->rsoc, di->sleep_sum_cap);
-+
-+ return sleep_soc;
-+}
-+
-+static void rk818_bat_power_supply_changed(struct rk818_battery *di)
-+{
-+ u8 status, thermal;
-+ static int old_soc = -1;
-+
-+ if (di->dsoc > 100)
-+ di->dsoc = 100;
-+ else if (di->dsoc < 0)
-+ di->dsoc = 0;
-+
-+ if (di->dsoc == old_soc)
-+ return;
-+
-+ thermal = rk818_bat_read(di, RK818_THERMAL_REG);
-+ status = rk818_bat_read(di, RK818_SUP_STS_REG);
-+ status = (status & CHRG_STATUS_MSK) >> 4;
-+ old_soc = di->dsoc;
-+ di->last_dsoc = di->dsoc;
-+ power_supply_changed(di->bat);
-+ BAT_INFO("changed: dsoc=%d, rsoc=%d, v=%d, ov=%d c=%d, "
-+ "cap=%d, f=%d, st=%s, hotdie=%d\n",
-+ di->dsoc, di->rsoc, di->voltage_avg, di->voltage_ocv,
-+ di->current_avg, di->remain_cap, di->fcc, bat_status[status],
-+ !!(thermal & HOTDIE_STS));
-+
-+ BAT_INFO("dl=%d, rl=%d, v=%d, halt=%d, halt_n=%d, max=%d, "
-+ "init=%d, sw=%d, calib=%d, below0=%d, force=%d\n",
-+ di->dbg_pwr_dsoc, di->dbg_pwr_rsoc, di->dbg_pwr_vol,
-+ di->is_halt, di->halt_cnt, di->is_max_soc_offset,
-+ di->is_initialized, di->is_sw_reset, di->is_ocv_calib,
-+ di->dbg_cap_low0, di->is_force_calib);
-+}
-+
-+static u8 rk818_bat_check_reboot(struct rk818_battery *di)
-+{
-+ u8 cnt;
-+
-+ cnt = rk818_bat_read(di, RK818_REBOOT_CNT_REG);
-+ cnt++;
-+
-+ if (cnt >= REBOOT_MAX_CNT) {
-+ BAT_INFO("reboot: %d --> %d\n", di->dsoc, di->rsoc);
-+ di->dsoc = di->rsoc;
-+ if (di->dsoc > 100)
-+ di->dsoc = 100;
-+ else if (di->dsoc < 0)
-+ di->dsoc = 0;
-+ rk818_bat_save_dsoc(di, di->dsoc);
-+ cnt = REBOOT_MAX_CNT;
-+ }
-+
-+ rk818_bat_save_reboot_cnt(di, cnt);
-+ DBG("reboot cnt: %d\n", cnt);
-+
-+ return cnt;
-+}
-+
-+static void rk818_bat_rsoc_daemon(struct rk818_battery *di)
-+{
-+ int est_vol, remain_cap;
-+ static unsigned long sec;
-+
-+ if ((di->remain_cap < 0) && (di->fb_blank != 0)) {
-+ if (!sec)
-+ sec = get_boot_sec();
-+ // wake_lock_timeout(&di->wake_lock,
-+ // (di->pdata->monitor_sec + 1) * HZ);
-+
-+ DBG("sec=%ld, hold_sec=%ld\n", sec, base2sec(sec));
-+ if (base2sec(sec) >= 60) {
-+ sec = 0;
-+ di->dbg_cap_low0++;
-+ est_vol = di->voltage_avg -
-+ (di->bat_res * di->current_avg) / 1000;
-+ remain_cap = rk818_bat_vol_to_ocvcap(di, est_vol);
-+ rk818_bat_init_capacity(di, remain_cap);
-+ BAT_INFO("adjust cap below 0 --> %d, rsoc=%d\n",
-+ di->remain_cap, di->rsoc);
-+ // wake_unlock(&di->wake_lock);
-+ }
-+ } else {
-+ sec = 0;
-+ }
-+}
-+
-+static void rk818_bat_update_info(struct rk818_battery *di)
-+{
-+ int is_charging;
-+
-+ di->voltage_avg = rk818_bat_get_avg_voltage(di);
-+ di->current_avg = rk818_bat_get_avg_current(di);
-+ di->voltage_relax = rk818_bat_get_relax_voltage(di);
-+ di->rsoc = rk818_bat_get_rsoc(di);
-+ di->remain_cap = rk818_bat_get_coulomb_cap(di);
-+ di->chrg_status = rk818_bat_get_chrg_status(di);
-+ is_charging = rk818_bat_get_charge_state(di);
-+ if (is_charging != di->is_charging) {
-+ di->is_charging = is_charging;
-+ if (is_charging)
-+ di->charge_count++;
-+ }
-+ if (di->voltage_avg > di->voltage_max)
-+ di->voltage_max = di->voltage_avg;
-+ if (di->current_avg > di->current_max)
-+ di->current_max = di->current_avg;
-+
-+ /* smooth charge */
-+ if (di->remain_cap > di->fcc) {
-+ di->sm_remain_cap -= (di->remain_cap - di->fcc);
-+ DBG("<%s>. cap: remain=%d, sm_remain=%d\n",
-+ __func__, di->remain_cap, di->sm_remain_cap);
-+ rk818_bat_init_coulomb_cap(di, di->fcc);
-+ }
-+
-+ if (di->chrg_status != CHARGE_FINISH)
-+ di->finish_base = get_boot_sec();
-+
-+ /*
-+ * we need update fcc in continuous charging state, if discharge state
-+ * keep at least 2 hour, we decide not to update fcc, so clear the
-+ * fcc update flag: age_allow_update.
-+ */
-+ if (base2min(di->plug_out_base) > 120)
-+ di->age_allow_update = false;
-+
-+ /* do adc calib: status must from cccv mode to finish mode */
-+ if (di->chrg_status == CC_OR_CV) {
-+ di->adc_allow_update = true;
-+ di->adc_calib_cnt = 0;
-+ }
-+}
-+
-+static void rk818_bat_init_ts1_detect(struct rk818_battery *di)
-+{
-+ u8 buf;
-+ u32 *ntc_table = di->pdata->ntc_table;
-+
-+ if (!di->pdata->ntc_size)
-+ return;
-+
-+ /* select ua */
-+ buf = rk818_bat_read(di, RK818_TS_CTRL_REG);
-+ buf &= ~TS1_CUR_MSK;
-+ /* chose suitable UA for temperature detect */
-+ if (ntc_table[0] < NTC_80UA_MAX_MEASURE) {
-+ di->pdata->ntc_factor = NTC_CALC_FACTOR_80UA;
-+ di->pdata->ntc_uA = 80;
-+ buf |= ADC_CUR_80UA;
-+ } else if (ntc_table[0] < NTC_60UA_MAX_MEASURE) {
-+ di->pdata->ntc_factor = NTC_CALC_FACTOR_60UA;
-+ di->pdata->ntc_uA = 60;
-+ buf |= ADC_CUR_60UA;
-+ } else if (ntc_table[0] < NTC_40UA_MAX_MEASURE) {
-+ di->pdata->ntc_factor = NTC_CALC_FACTOR_40UA;
-+ di->pdata->ntc_uA = 40;
-+ buf |= ADC_CUR_40UA;
-+ } else {
-+ di->pdata->ntc_factor = NTC_CALC_FACTOR_20UA;
-+ di->pdata->ntc_uA = 20;
-+ buf |= ADC_CUR_20UA;
-+ }
-+ rk818_bat_write(di, RK818_TS_CTRL_REG, buf);
-+
-+ /* enable ADC_TS1_EN */
-+ buf = rk818_bat_read(di, RK818_ADC_CTRL_REG);
-+ buf |= ADC_TS1_EN;
-+ rk818_bat_write(di, RK818_ADC_CTRL_REG, buf);
-+}
-+
-+/*
-+ * Due to hardware design issue, Vdelta = "(R_sample + R_other) * I_avg" will be
-+ * included into TS1 adc value. We must subtract it to get correct adc value.
-+ * The solution:
-+ *
-+ * (1) calculate Vdelta:
-+ *
-+ * adc1 - Vdelta ua1 (adc2 * ua1) - (adc1 * ua2)
-+ * ------------- = ----- ==> equals: Vdelta = -----------------------------
-+ * adc2 - Vdelta ua2 ua1 - ua2
-+ *
-+ *
-+ * (2) calculate correct ADC value:
-+ *
-+ * charging: ADC = adc1 - abs(Vdelta);
-+ * discharging: ADC = adc1 + abs(Vdelta);
-+ */
-+static int rk818_bat_get_ntc_res(struct rk818_battery *di)
-+{
-+ int adc1 = 0, adc2 = 0;
-+ int ua1, ua2, v_delta, res, val;
-+ u8 buf;
-+
-+ /* read sample ua1 */
-+ buf = rk818_bat_read(di, RK818_TS_CTRL_REG);
-+ DBG("<%s>. read adc1, sample uA=%d\n",
-+ __func__, ((buf & 0x03) + 1) * 20);
-+
-+ /* read adc adc1 */
-+ ua1 = di->pdata->ntc_uA;
-+ adc1 |= rk818_bat_read(di, RK818_TS1_ADC_REGL) << 0;
-+ adc1 |= rk818_bat_read(di, RK818_TS1_ADC_REGH) << 8;
-+
-+ /* chose reference UA for adc2 */
-+ ua2 = (ua1 != 20) ? 20 : 40;
-+ buf = rk818_bat_read(di, RK818_TS_CTRL_REG);
-+ buf &= ~TS1_CUR_MSK;
-+ buf |= ((ua2 - 20) / 20);
-+ rk818_bat_write(di, RK818_TS_CTRL_REG, buf);
-+
-+ /* read adc adc2 */
-+ msleep(1000);
-+
-+ /* read sample ua2 */
-+ buf = rk818_bat_read(di, RK818_TS_CTRL_REG);
-+ DBG("<%s>. read adc2, sample uA=%d\n",
-+ __func__, ((buf & 0x03) + 1) * 20);
-+
-+ adc2 |= rk818_bat_read(di, RK818_TS1_ADC_REGL) << 0;
-+ adc2 |= rk818_bat_read(di, RK818_TS1_ADC_REGH) << 8;
-+
-+ DBG("<%s>. ua1=%d, ua2=%d, adc1=%d, adc2=%d\n",
-+ __func__, ua1, ua2, adc1, adc2);
-+
-+ /* calculate delta voltage */
-+ if (adc2 != adc1)
-+ v_delta = abs((adc2 * ua1 - adc1 * ua2) / (ua2 - ua1));
-+ else
-+ v_delta = 0;
-+
-+ /* considering current avg direction, calcuate real adc value */
-+ val = (di->current_avg >= 0) ? (adc1 - v_delta) : (adc1 + v_delta);
-+
-+ DBG("<%s>. Iavg=%d, Vdelta=%d, Vadc=%d\n",
-+ __func__, di->current_avg, v_delta, val);
-+
-+ res = val * di->pdata->ntc_factor;
-+
-+ DBG("<%s>. val=%d, ntc_res=%d, ntc_factor=%d, Rdelta=%d\n",
-+ __func__, val, res, di->pdata->ntc_factor,
-+ v_delta * di->pdata->ntc_factor);
-+
-+ DBG("<%s>. t=[%d'C(%d) ~ %dC(%d)]\n", __func__,
-+ di->pdata->ntc_degree_from, di->pdata->ntc_table[0],
-+ di->pdata->ntc_degree_from + di->pdata->ntc_size - 1,
-+ di->pdata->ntc_table[di->pdata->ntc_size - 1]);
-+
-+ rk818_bat_init_ts1_detect(di);
-+
-+ return res;
-+}
-+
-+static BLOCKING_NOTIFIER_HEAD(rk818_bat_notifier_chain);
-+
-+int rk818_bat_temp_notifier_register(struct notifier_block *nb)
-+{
-+ return blocking_notifier_chain_register(&rk818_bat_notifier_chain, nb);
-+}
-+
-+int rk818_bat_temp_notifier_unregister(struct notifier_block *nb)
-+{
-+ return blocking_notifier_chain_unregister(&rk818_bat_notifier_chain, nb);
-+}
-+
-+static void rk818_bat_temp_notifier_callback(int temp)
-+{
-+ blocking_notifier_call_chain(&rk818_bat_notifier_chain, temp, NULL);
-+}
-+
-+static void rk818_bat_update_temperature(struct rk818_battery *di)
-+{
-+ static int old_temp, first_time = 1;
-+ u32 ntc_size, *ntc_table;
-+ int i, res, temp;
-+
-+ ntc_table = di->pdata->ntc_table;
-+ ntc_size = di->pdata->ntc_size;
-+ di->temperature = VIRTUAL_TEMPERATURE;
-+
-+ if (ntc_size) {
-+ res = rk818_bat_get_ntc_res(di);
-+ if (res < ntc_table[ntc_size - 1]) {
-+ di->temperature = di->pdata->ntc_degree_from +
-+ di->pdata->ntc_size - 1;
-+ BAT_INFO("bat ntc upper max degree: R=%d\n", res);
-+ } else if (res > ntc_table[0]) {
-+ di->temperature = di->pdata->ntc_degree_from;
-+ BAT_INFO("bat ntc lower min degree: R=%d\n", res);
-+ } else {
-+ for (i = 0; i < ntc_size; i++) {
-+ if (res >= ntc_table[i])
-+ break;
-+ }
-+
-+ /* if first in, init old_temp */
-+ temp = (i + di->pdata->ntc_degree_from) * 10;
-+ if (first_time == 1) {
-+ di->temperature = temp;
-+ old_temp = temp;
-+ first_time = 0;
-+ }
-+
-+ /*
-+ * compare with old one, it's invalid when over 50
-+ * and we should use old data.
-+ */
-+ if (abs(temp - old_temp) > 50)
-+ temp = old_temp;
-+ else
-+ old_temp = temp;
-+
-+ di->temperature = temp;
-+ DBG("<%s>. temperature = %d\n",
-+ __func__, di->temperature);
-+ rk818_bat_temp_notifier_callback(di->temperature / 10);
-+ }
-+ }
-+}
-+
-+static void rk818_bat_init_dsoc_algorithm(struct rk818_battery *di)
-+{
-+ u8 buf;
-+ int16_t rest = 0;
-+ unsigned long soc_sec;
-+ const char *mode_name[] = { "MODE_ZERO", "MODE_FINISH",
-+ "MODE_SMOOTH_CHRG", "MODE_SMOOTH_DISCHRG", "MODE_SMOOTH", };
-+
-+ /* get rest */
-+ rest |= rk818_bat_read(di, RK818_CALC_REST_REGH) << 8;
-+ rest |= rk818_bat_read(di, RK818_CALC_REST_REGL) << 0;
-+
-+ /* get mode */
-+ buf = rk818_bat_read(di, RK818_MISC_MARK_REG);
-+ di->algo_rest_mode = (buf & ALGO_REST_MODE_MSK) >> ALGO_REST_MODE_SHIFT;
-+
-+ if (rk818_bat_get_chrg_status(di) == CHARGE_FINISH) {
-+ if (di->algo_rest_mode == MODE_FINISH) {
-+ soc_sec = di->fcc * 3600 / 100 / FINISH_CHRG_CUR1;
-+ if ((rest / DIV(soc_sec)) > 0) {
-+ if (di->dsoc < 100) {
-+ di->dsoc++;
-+ di->algo_rest_val = rest % soc_sec;
-+ BAT_INFO("algorithm rest(%d) dsoc "
-+ "inc: %d\n",
-+ rest, di->dsoc);
-+ } else {
-+ di->algo_rest_val = 0;
-+ }
-+ } else {
-+ di->algo_rest_val = rest;
-+ }
-+ } else {
-+ di->algo_rest_val = rest;
-+ }
-+ } else {
-+ /* charge speed up */
-+ if ((rest / 1000) > 0 && rk818_bat_chrg_online(di)) {
-+ if (di->dsoc < di->rsoc) {
-+ di->dsoc++;
-+ di->algo_rest_val = rest % 1000;
-+ BAT_INFO("algorithm rest(%d) dsoc inc: %d\n",
-+ rest, di->dsoc);
-+ } else {
-+ di->algo_rest_val = 0;
-+ }
-+ /* discharge speed up */
-+ } else if (((rest / 1000) < 0) && !rk818_bat_chrg_online(di)) {
-+ if (di->dsoc > di->rsoc) {
-+ di->dsoc--;
-+ di->algo_rest_val = rest % 1000;
-+ BAT_INFO("algorithm rest(%d) dsoc sub: %d\n",
-+ rest, di->dsoc);
-+ } else {
-+ di->algo_rest_val = 0;
-+ }
-+ } else {
-+ di->algo_rest_val = rest;
-+ }
-+ }
-+
-+ if (di->dsoc >= 100)
-+ di->dsoc = 100;
-+ else if (di->dsoc <= 0)
-+ di->dsoc = 0;
-+
-+ /* init current mode */
-+ di->voltage_avg = rk818_bat_get_avg_voltage(di);
-+ di->current_avg = rk818_bat_get_avg_current(di);
-+ if (rk818_bat_get_chrg_status(di) == CHARGE_FINISH) {
-+ rk818_bat_finish_algo_prepare(di);
-+ di->work_mode = MODE_FINISH;
-+ } else {
-+ rk818_bat_smooth_algo_prepare(di);
-+ di->work_mode = MODE_SMOOTH;
-+ }
-+
-+ DBG("<%s>. init: org_rest=%d, rest=%d, mode=%s; "
-+ "doc(x1000): zero=%d, chrg=%d, dischrg=%d, finish=%lu\n",
-+ __func__, rest, di->algo_rest_val, mode_name[di->algo_rest_mode],
-+ di->zero_dsoc, di->sm_chrg_dsoc, di->sm_dischrg_dsoc,
-+ di->finish_base);
-+}
-+
-+static void rk818_bat_save_algo_rest(struct rk818_battery *di)
-+{
-+ u8 buf, mode;
-+ int16_t algo_rest = 0;
-+ int tmp_soc;
-+ int zero_rest = 0, sm_chrg_rest = 0;
-+ int sm_dischrg_rest = 0, finish_rest = 0;
-+ const char *mode_name[] = { "MODE_ZERO", "MODE_FINISH",
-+ "MODE_SMOOTH_CHRG", "MODE_SMOOTH_DISCHRG", "MODE_SMOOTH", };
-+
-+ /* zero dischrg */
-+ tmp_soc = (di->zero_dsoc) / 1000;
-+ if (tmp_soc == di->dsoc)
-+ zero_rest = di->zero_dsoc - ((di->dsoc + 1) * 1000 -
-+ MIN_ACCURACY);
-+
-+ /* sm chrg */
-+ tmp_soc = di->sm_chrg_dsoc / 1000;
-+ if (tmp_soc == di->dsoc)
-+ sm_chrg_rest = di->sm_chrg_dsoc - di->dsoc * 1000;
-+
-+ /* sm dischrg */
-+ tmp_soc = (di->sm_dischrg_dsoc) / 1000;
-+ if (tmp_soc == di->dsoc)
-+ sm_dischrg_rest = di->sm_dischrg_dsoc - ((di->dsoc + 1) * 1000 -
-+ MIN_ACCURACY);
-+
-+ /* last time is also finish chrg, then add last rest */
-+ if (di->algo_rest_mode == MODE_FINISH && di->algo_rest_val)
-+ finish_rest = base2sec(di->finish_base) + di->algo_rest_val;
-+ else
-+ finish_rest = base2sec(di->finish_base);
-+
-+ /* total calc */
-+ if ((rk818_bat_chrg_online(di) && (di->dsoc > di->rsoc)) ||
-+ (!rk818_bat_chrg_online(di) && (di->dsoc < di->rsoc)) ||
-+ (di->dsoc == di->rsoc)) {
-+ di->algo_rest_val = 0;
-+ algo_rest = 0;
-+ DBG("<%s>. step1..\n", __func__);
-+ } else if (di->work_mode == MODE_FINISH) {
-+ algo_rest = finish_rest;
-+ DBG("<%s>. step2..\n", __func__);
-+ } else if (di->algo_rest_mode == MODE_FINISH) {
-+ algo_rest = zero_rest + sm_dischrg_rest + sm_chrg_rest;
-+ DBG("<%s>. step3..\n", __func__);
-+ } else {
-+ if (rk818_bat_chrg_online(di) && (di->dsoc < di->rsoc))
-+ algo_rest = sm_chrg_rest + di->algo_rest_val;
-+ else if (!rk818_bat_chrg_online(di) && (di->dsoc > di->rsoc))
-+ algo_rest = zero_rest + sm_dischrg_rest +
-+ di->algo_rest_val;
-+ else
-+ algo_rest = zero_rest + sm_dischrg_rest + sm_chrg_rest +
-+ di->algo_rest_val;
-+ DBG("<%s>. step4..\n", __func__);
-+ }
-+
-+ /* check mode */
-+ if ((di->work_mode == MODE_FINISH) || (di->work_mode == MODE_ZERO)) {
-+ mode = di->work_mode;
-+ } else {/* MODE_SMOOTH */
-+ if (di->sm_linek > 0)
-+ mode = MODE_SMOOTH_CHRG;
-+ else
-+ mode = MODE_SMOOTH_DISCHRG;
-+ }
-+
-+ /* save mode */
-+ buf = rk818_bat_read(di, RK818_MISC_MARK_REG);
-+ buf &= ~ALGO_REST_MODE_MSK;
-+ buf |= (mode << ALGO_REST_MODE_SHIFT);
-+ rk818_bat_write(di, RK818_MISC_MARK_REG, buf);
-+
-+ /* save rest */
-+ buf = (algo_rest >> 8) & 0xff;
-+ rk818_bat_write(di, RK818_CALC_REST_REGH, buf);
-+ buf = (algo_rest >> 0) & 0xff;
-+ rk818_bat_write(di, RK818_CALC_REST_REGL, buf);
-+
-+ DBG("<%s>. rest: algo=%d, mode=%s, last_rest=%d; zero=%d, "
-+ "chrg=%d, dischrg=%d, finish=%lu\n",
-+ __func__, algo_rest, mode_name[mode], di->algo_rest_val, zero_rest,
-+ sm_chrg_rest, sm_dischrg_rest, base2sec(di->finish_base));
-+}
-+
-+static void rk818_bat_save_data(struct rk818_battery *di)
-+{
-+ rk818_bat_save_dsoc(di, di->dsoc);
-+ rk818_bat_save_cap(di, di->remain_cap);
-+ rk818_bat_save_algo_rest(di);
-+}
-+
-+static void rk818_battery_work(struct work_struct *work)
-+{
-+ struct rk818_battery *di =
-+ container_of(work, struct rk818_battery, bat_delay_work.work);
-+
-+ rk818_bat_update_info(di);
-+ rk818_bat_wait_finish_sig(di);
-+ rk818_bat_rsoc_daemon(di);
-+ rk818_bat_update_temperature(di);
-+ rk818_bat_display_smooth(di);
-+ rk818_bat_power_supply_changed(di);
-+ rk818_bat_save_data(di);
-+ rk818_bat_debug_info(di);
-+
-+ queue_delayed_work(di->bat_monitor_wq, &di->bat_delay_work,
-+ msecs_to_jiffies(di->monitor_ms));
-+}
-+
-+static irqreturn_t rk818_vb_low_irq(int irq, void *bat)
-+{
-+ struct rk818_battery *di = (struct rk818_battery *)bat;
-+
-+ di->dsoc = 0;
-+ rk_send_wakeup_key();
-+ BAT_INFO("lower power yet, power off system! v=%d, c=%d, dsoc=%d\n",
-+ di->voltage_avg, di->current_avg, di->dsoc);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void rk818_bat_init_sysfs(struct rk818_battery *di)
-+{
-+ int i, ret;
-+
-+ for (i = 0; i < ARRAY_SIZE(rk818_bat_attr); i++) {
-+ ret = sysfs_create_file(&di->dev->kobj,
-+ &rk818_bat_attr[i].attr);
-+ if (ret)
-+ dev_err(di->dev, "create bat node(%s) error\n",
-+ rk818_bat_attr[i].attr.name);
-+ }
-+}
-+
-+static int rk818_bat_init_irqs(struct rk818_battery *di)
-+{
-+ struct rk808 *rk818 = di->rk818;
-+ struct platform_device *pdev = di->pdev;
-+ int ret, vb_lo_irq;
-+
-+ vb_lo_irq = regmap_irq_get_virq(rk818->irq_data, RK818_IRQ_VB_LO);
-+ if (vb_lo_irq < 0) {
-+ dev_err(di->dev, "vb_lo_irq request failed!\n");
-+ return vb_lo_irq;
-+ }
-+
-+ ret = devm_request_threaded_irq(di->dev, vb_lo_irq, NULL,
-+ rk818_vb_low_irq,
-+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-+ "rk818_vb_low", di);
-+ if (ret) {
-+ dev_err(&pdev->dev, "vb_lo_irq request failed!\n");
-+ return ret;
-+ }
-+ enable_irq_wake(vb_lo_irq);
-+
-+ return 0;
-+}
-+
-+static void rk818_bat_init_info(struct rk818_battery *di)
-+{
-+ di->design_cap = di->pdata->design_capacity;
-+ di->qmax = di->pdata->design_qmax;
-+ di->bat_res = di->pdata->bat_res;
-+ di->monitor_ms = di->pdata->monitor_sec * TIMER_MS_COUNTS;
-+ di->boot_base = POWER_ON_SEC_BASE;
-+ di->res_div = (di->pdata->sample_res == SAMPLE_RES_20MR) ?
-+ SAMPLE_RES_DIV1 : SAMPLE_RES_DIV2;
-+}
-+
-+static time64_t rk818_get_rtc_sec(void)
-+{
-+ int err;
-+ struct rtc_time tm;
-+ struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
-+
-+ err = rtc_read_time(rtc, &tm);
-+ if (err) {
-+ dev_err(rtc->dev.parent, "read hardware clk failed\n");
-+ return 0;
-+ }
-+
-+ err = rtc_valid_tm(&tm);
-+ if (err) {
-+ dev_err(rtc->dev.parent, "invalid date time\n");
-+ return 0;
-+ }
-+
-+ return rtc_tm_to_time64(&tm);
-+}
-+
-+static int rk818_bat_rtc_sleep_sec(struct rk818_battery *di)
-+{
-+ int interval_sec;
-+
-+ interval_sec = rk818_get_rtc_sec() - di->rtc_base;
-+
-+ return (interval_sec > 0) ? interval_sec : 0;
-+}
-+
-+static void rk818_bat_set_shtd_vol(struct rk818_battery *di)
-+{
-+ u8 val;
-+
-+ /* set vbat lowest 3.0v shutdown */
-+ val = rk818_bat_read(di, RK818_VB_MON_REG);
-+ val &= ~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK);
-+ val |= (RK818_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN);
-+ rk818_bat_write(di, RK818_VB_MON_REG, val);
-+
-+ /* disable low irq */
-+ rk818_bat_set_bits(di, RK818_INT_STS_MSK_REG1,
-+ VB_LOW_INT_EN, VB_LOW_INT_EN);
-+}
-+
-+static void rk818_bat_init_fg(struct rk818_battery *di)
-+{
-+ rk818_bat_enable_gauge(di);
-+ rk818_bat_init_voltage_kb(di);
-+ rk818_bat_init_coffset(di);
-+ rk818_bat_set_relax_sample(di);
-+ rk818_bat_set_ioffset_sample(di);
-+ rk818_bat_set_ocv_sample(di);
-+ rk818_bat_init_ts1_detect(di);
-+ rk818_bat_init_rsoc(di);
-+ rk818_bat_init_coulomb_cap(di, di->nac);
-+ rk818_bat_init_age_algorithm(di);
-+ rk818_bat_init_chrg_config(di);
-+ rk818_bat_set_shtd_vol(di);
-+ rk818_bat_init_zero_table(di);
-+ rk818_bat_init_caltimer(di);
-+ rk818_bat_init_dsoc_algorithm(di);
-+
-+ di->voltage_avg = rk818_bat_get_avg_voltage(di);
-+ di->voltage_ocv = rk818_bat_get_ocv_voltage(di);
-+ di->voltage_relax = rk818_bat_get_relax_voltage(di);
-+ di->current_avg = rk818_bat_get_avg_current(di);
-+ di->remain_cap = rk818_bat_get_coulomb_cap(di);
-+ di->dbg_pwr_dsoc = di->dsoc;
-+ di->dbg_pwr_rsoc = di->rsoc;
-+ di->dbg_pwr_vol = di->voltage_avg;
-+
-+ rk818_bat_dump_regs(di, 0x99, 0xee);
-+ DBG("nac=%d cap=%d ov=%d v=%d rv=%d dl=%d rl=%d c=%d\n",
-+ di->nac, di->remain_cap, di->voltage_ocv, di->voltage_avg,
-+ di->voltage_relax, di->dsoc, di->rsoc, di->current_avg);
-+}
-+
-+#ifdef CONFIG_OF
-+static int rk818_bat_parse_dt(struct rk818_battery *di)
-+{
-+ u32 out_value;
-+ int length, ret;
-+ size_t size;
-+ struct device_node *np = di->dev->of_node;
-+ struct battery_platform_data *pdata;
-+ struct device *dev = di->dev;
-+
-+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
-+ if (!pdata)
-+ return -ENOMEM;
-+
-+ di->pdata = pdata;
-+ /* init default param */
-+ pdata->bat_res = DEFAULT_BAT_RES;
-+ pdata->monitor_sec = DEFAULT_MONITOR_SEC;
-+ pdata->pwroff_vol = DEFAULT_PWROFF_VOL_THRESD;
-+ pdata->sleep_exit_current = DEFAULT_SLP_EXIT_CUR;
-+ pdata->sleep_enter_current = DEFAULT_SLP_ENTER_CUR;
-+ pdata->bat_mode = MODE_BATTARY;
-+ pdata->max_soc_offset = DEFAULT_MAX_SOC_OFFSET;
-+ pdata->sample_res = DEFAULT_SAMPLE_RES;
-+ pdata->energy_mode = DEFAULT_ENERGY_MODE;
-+ pdata->fb_temp = DEFAULT_FB_TEMP;
-+ pdata->zero_reserve_dsoc = DEFAULT_ZERO_RESERVE_DSOC;
-+
-+ /* parse necessary param */
-+ if (!of_find_property(np, "ocv_table", &length)) {
-+ dev_err(dev, "ocv_table not found!\n");
-+ return -EINVAL;
-+ }
-+
-+ pdata->ocv_size = length / sizeof(u32);
-+ if (pdata->ocv_size <= 0) {
-+ dev_err(dev, "invalid ocv table\n");
-+ return -EINVAL;
-+ }
-+
-+ size = sizeof(*pdata->ocv_table) * pdata->ocv_size;
-+ pdata->ocv_table = devm_kzalloc(di->dev, size, GFP_KERNEL);
-+ if (!pdata->ocv_table)
-+ return -ENOMEM;
-+
-+ ret = of_property_read_u32_array(np, "ocv_table",
-+ pdata->ocv_table,
-+ pdata->ocv_size);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = of_property_read_u32(np, "design_capacity", &out_value);
-+ if (ret < 0) {
-+ dev_err(dev, "design_capacity not found!\n");
-+ return ret;
-+ }
-+ pdata->design_capacity = out_value;
-+
-+ ret = of_property_read_u32(np, "design_qmax", &out_value);
-+ if (ret < 0) {
-+ dev_err(dev, "design_qmax not found!\n");
-+ return ret;
-+ }
-+ pdata->design_qmax = out_value;
-+ ret = of_property_read_u32(np, "max_chrg_voltage", &out_value);
-+ if (ret < 0) {
-+ dev_err(dev, "max_chrg_voltage missing!\n");
-+ return ret;
-+ }
-+ pdata->max_chrg_voltage = out_value;
-+ if (out_value >= 4300)
-+ pdata->zero_algorithm_vol = DEFAULT_ALGR_VOL_THRESD2;
-+ else
-+ pdata->zero_algorithm_vol = DEFAULT_ALGR_VOL_THRESD1;
-+
-+ ret = of_property_read_u32(np, "fb_temperature", &pdata->fb_temp);
-+ if (ret < 0)
-+ dev_err(dev, "fb_temperature missing!\n");
-+
-+ ret = of_property_read_u32(np, "sample_res", &pdata->sample_res);
-+ if (ret < 0)
-+ dev_err(dev, "sample_res missing!\n");
-+
-+ ret = of_property_read_u32(np, "energy_mode", &pdata->energy_mode);
-+ if (ret < 0)
-+ dev_err(dev, "energy_mode missing!\n");
-+
-+ ret = of_property_read_u32(np, "max_soc_offset",
-+ &pdata->max_soc_offset);
-+ if (ret < 0)
-+ dev_err(dev, "max_soc_offset missing!\n");
-+
-+ ret = of_property_read_u32(np, "monitor_sec", &pdata->monitor_sec);
-+ if (ret < 0)
-+ dev_err(dev, "monitor_sec missing!\n");
-+
-+ ret = of_property_read_u32(np, "zero_algorithm_vol",
-+ &pdata->zero_algorithm_vol);
-+ if (ret < 0)
-+ dev_err(dev, "zero_algorithm_vol missing!\n");
-+
-+ ret = of_property_read_u32(np, "zero_reserve_dsoc",
-+ &pdata->zero_reserve_dsoc);
-+
-+ ret = of_property_read_u32(np, "virtual_power", &pdata->bat_mode);
-+ if (ret < 0)
-+ dev_err(dev, "virtual_power missing!\n");
-+
-+ ret = of_property_read_u32(np, "bat_res", &pdata->bat_res);
-+ if (ret < 0)
-+ dev_err(dev, "bat_res missing!\n");
-+
-+ ret = of_property_read_u32(np, "sleep_enter_current",
-+ &pdata->sleep_enter_current);
-+ if (ret < 0)
-+ dev_err(dev, "sleep_enter_current missing!\n");
-+
-+ ret = of_property_read_u32(np, "sleep_exit_current",
-+ &pdata->sleep_exit_current);
-+ if (ret < 0)
-+ dev_err(dev, "sleep_exit_current missing!\n");
-+
-+ ret = of_property_read_u32(np, "power_off_thresd", &pdata->pwroff_vol);
-+ if (ret < 0)
-+ dev_err(dev, "power_off_thresd missing!\n");
-+
-+ if (!of_find_property(np, "ntc_table", &length)) {
-+ pdata->ntc_size = 0;
-+ } else {
-+ /* get ntc degree base value */
-+ ret = of_property_read_u32_index(np, "ntc_degree_from", 1,
-+ &pdata->ntc_degree_from);
-+ if (ret) {
-+ dev_err(dev, "invalid ntc_degree_from\n");
-+ return -EINVAL;
-+ }
-+
-+ of_property_read_u32_index(np, "ntc_degree_from", 0,
-+ &out_value);
-+ if (out_value)
-+ pdata->ntc_degree_from = -pdata->ntc_degree_from;
-+
-+ pdata->ntc_size = length / sizeof(u32);
-+ }
-+
-+ if (pdata->ntc_size) {
-+ size = sizeof(*pdata->ntc_table) * pdata->ntc_size;
-+ pdata->ntc_table = devm_kzalloc(di->dev, size, GFP_KERNEL);
-+ if (!pdata->ntc_table)
-+ return -ENOMEM;
-+
-+ ret = of_property_read_u32_array(np, "ntc_table",
-+ pdata->ntc_table,
-+ pdata->ntc_size);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ DBG("the battery dts info dump:\n"
-+ "bat_res:%d\n"
-+ "design_capacity:%d\n"
-+ "design_qmax :%d\n"
-+ "sleep_enter_current:%d\n"
-+ "sleep_exit_current:%d\n"
-+ "zero_algorithm_vol:%d\n"
-+ "zero_reserve_dsoc:%d\n"
-+ "monitor_sec:%d\n"
-+ "max_soc_offset:%d\n"
-+ "virtual_power:%d\n"
-+ "pwroff_vol:%d\n"
-+ "sample_res:%d\n"
-+ "ntc_size=%d\n"
-+ "ntc_degree_from:%d\n"
-+ "ntc_degree_to:%d\n",
-+ pdata->bat_res, pdata->design_capacity, pdata->design_qmax,
-+ pdata->sleep_enter_current, pdata->sleep_exit_current,
-+ pdata->zero_algorithm_vol, pdata->zero_reserve_dsoc,
-+ pdata->monitor_sec,
-+ pdata->max_soc_offset, pdata->bat_mode, pdata->pwroff_vol,
-+ pdata->sample_res, pdata->ntc_size, pdata->ntc_degree_from,
-+ pdata->ntc_degree_from + pdata->ntc_size - 1
-+ );
-+
-+ return 0;
-+}
-+#else
-+static int rk818_bat_parse_dt(struct rk818_battery *di)
-+{
-+ return -ENODEV;
-+}
-+#endif
-+
-+static const struct of_device_id rk818_battery_of_match[] = {
-+ {.compatible = "rk818-battery",},
-+ { },
-+};
-+
-+static int rk818_battery_probe(struct platform_device *pdev)
-+{
-+ const struct of_device_id *of_id =
-+ of_match_device(rk818_battery_of_match, &pdev->dev);
-+ struct rk818_battery *di;
-+ struct rk808 *rk818 = dev_get_drvdata(pdev->dev.parent);
-+ int ret;
-+
-+ if (!of_id) {
-+ dev_err(&pdev->dev, "Failed to find matching dt id\n");
-+ return -ENODEV;
-+ }
-+
-+ di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
-+ if (!di)
-+ return -ENOMEM;
-+
-+ di->rk818 = rk818;
-+ di->pdev = pdev;
-+ di->dev = &pdev->dev;
-+ di->regmap = rk818->regmap;
-+ platform_set_drvdata(pdev, di);
-+
-+ ret = rk818_bat_parse_dt(di);
-+ if (ret < 0) {
-+ dev_err(di->dev, "rk818 battery parse dt failed!\n");
-+ return ret;
-+ }
-+
-+ if (!is_rk818_bat_exist(di)) {
-+ di->pdata->bat_mode = MODE_VIRTUAL;
-+ dev_err(di->dev, "no battery, virtual power mode\n");
-+ }
-+
-+ ret = rk818_bat_init_irqs(di);
-+ if (ret != 0) {
-+ dev_err(di->dev, "rk818 bat init irqs failed!\n");
-+ return ret;
-+ }
-+
-+ ret = rk818_bat_init_power_supply(di);
-+ if (ret) {
-+ dev_err(di->dev, "rk818 power supply register failed!\n");
-+ return ret;
-+ }
-+
-+ rk818_bat_init_info(di);
-+ rk818_bat_init_fg(di);
-+ rk818_bat_init_sysfs(di);
-+ rk818_bat_register_fb_notify(di);
-+ //wake_lock_init(&di->wake_lock, WAKE_LOCK_SUSPEND, "rk818_bat_lock");
-+ di->bat_monitor_wq = alloc_ordered_workqueue("%s",
-+ WQ_MEM_RECLAIM | WQ_FREEZABLE, "rk818-bat-monitor-wq");
-+ INIT_DELAYED_WORK(&di->bat_delay_work, rk818_battery_work);
-+ queue_delayed_work(di->bat_monitor_wq, &di->bat_delay_work,
-+ msecs_to_jiffies(TIMER_MS_COUNTS * 5));
-+
-+ BAT_INFO("driver version %s\n", DRIVER_VERSION);
-+
-+ return ret;
-+}
-+
-+static int rk818_battery_suspend(struct platform_device *dev,
-+ pm_message_t state)
-+{
-+ struct rk818_battery *di = platform_get_drvdata(dev);
-+ u8 val, st;
-+
-+ cancel_delayed_work_sync(&di->bat_delay_work);
-+
-+ di->s2r = false;
-+ di->sleep_chrg_online = rk818_bat_chrg_online(di);
-+ di->sleep_chrg_status = rk818_bat_get_chrg_status(di);
-+ di->current_avg = rk818_bat_get_avg_current(di);
-+ di->remain_cap = rk818_bat_get_coulomb_cap(di);
-+ di->rsoc = rk818_bat_get_rsoc(di);
-+ di->rtc_base = rk818_get_rtc_sec();
-+ rk818_bat_save_data(di);
-+ st = (rk818_bat_read(di, RK818_SUP_STS_REG) & CHRG_STATUS_MSK) >> 4;
-+
-+ /* if not CHARGE_FINISH, reinit finish_base.
-+ * avoid sleep loop between suspend and resume
-+ */
-+ if (di->sleep_chrg_status != CHARGE_FINISH)
-+ di->finish_base = get_boot_sec();
-+
-+ /* avoid: enter suspend from MODE_ZERO: load from heavy to light */
-+ if ((di->work_mode == MODE_ZERO) &&
-+ (di->sleep_chrg_online) && (di->current_avg >= 0)) {
-+ DBG("suspend: MODE_ZERO exit...\n");
-+ /* it need't do prepare for mode finish and smooth, it will
-+ * be done in display_smooth
-+ */
-+ if (di->sleep_chrg_status == CHARGE_FINISH) {
-+ di->work_mode = MODE_FINISH;
-+ di->finish_base = get_boot_sec();
-+ } else {
-+ di->work_mode = MODE_SMOOTH;
-+ rk818_bat_smooth_algo_prepare(di);
-+ }
-+ }
-+
-+ /* set vbat low than 3.4v to generate a wakeup irq */
-+ val = rk818_bat_read(di, RK818_VB_MON_REG);
-+ val &= (~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
-+ val |= (RK818_VBAT_LOW_3V4 | EN_VBAT_LOW_IRQ);
-+ rk818_bat_write(di, RK818_VB_MON_REG, val);
-+ rk818_bat_set_bits(di, RK818_INT_STS_MSK_REG1, VB_LOW_INT_EN, 0);
-+
-+ BAT_INFO("suspend: dl=%d rl=%d c=%d v=%d cap=%d at=%ld ch=%d st=%s\n",
-+ di->dsoc, di->rsoc, di->current_avg,
-+ rk818_bat_get_avg_voltage(di), rk818_bat_get_coulomb_cap(di),
-+ di->sleep_dischrg_sec, di->sleep_chrg_online, bat_status[st]);
-+
-+ return 0;
-+}
-+
-+static int rk818_battery_resume(struct platform_device *dev)
-+{
-+ struct rk818_battery *di = platform_get_drvdata(dev);
-+ int interval_sec, time_step, pwroff_vol;
-+ u8 val, st;
-+
-+ di->s2r = true;
-+ di->current_avg = rk818_bat_get_avg_current(di);
-+ di->voltage_relax = rk818_bat_get_relax_voltage(di);
-+ di->voltage_avg = rk818_bat_get_avg_voltage(di);
-+ di->remain_cap = rk818_bat_get_coulomb_cap(di);
-+ di->rsoc = rk818_bat_get_rsoc(di);
-+ interval_sec = rk818_bat_rtc_sleep_sec(di);
-+ di->sleep_sum_sec += interval_sec;
-+ pwroff_vol = di->pdata->pwroff_vol;
-+ st = (rk818_bat_read(di, RK818_SUP_STS_REG) & CHRG_STATUS_MSK) >> 4;
-+
-+ if (!di->sleep_chrg_online) {
-+ /* only add up discharge sleep seconds */
-+ di->sleep_dischrg_sec += interval_sec;
-+ if (di->voltage_avg <= pwroff_vol + 50)
-+ time_step = DISCHRG_TIME_STEP1;
-+ else
-+ time_step = DISCHRG_TIME_STEP2;
-+ }
-+
-+ BAT_INFO("resume: dl=%d rl=%d c=%d v=%d rv=%d "
-+ "cap=%d dt=%d at=%ld ch=%d st=%s\n",
-+ di->dsoc, di->rsoc, di->current_avg, di->voltage_avg,
-+ di->voltage_relax, rk818_bat_get_coulomb_cap(di), interval_sec,
-+ di->sleep_dischrg_sec, di->sleep_chrg_online, bat_status[st]);
-+
-+ /* sleep: enough time and discharge */
-+ if ((di->sleep_dischrg_sec > time_step) && (!di->sleep_chrg_online)) {
-+ if (rk818_bat_sleep_dischrg(di))
-+ di->sleep_dischrg_sec = 0;
-+ }
-+
-+ rk818_bat_save_data(di);
-+
-+ /* set vbat lowest 3.0v shutdown */
-+ val = rk818_bat_read(di, RK818_VB_MON_REG);
-+ val &= ~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK);
-+ val |= (RK818_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN);
-+ rk818_bat_write(di, RK818_VB_MON_REG, val);
-+ rk818_bat_set_bits(di, RK818_INT_STS_MSK_REG1,
-+ VB_LOW_INT_EN, VB_LOW_INT_EN);
-+
-+ /* charge/lowpower lock: for battery work to update dsoc and rsoc */
-+ // if ((di->sleep_chrg_online) ||
-+ // (!di->sleep_chrg_online && di->voltage_avg < di->pdata->pwroff_vol))
-+ // wake_lock_timeout(&di->wake_lock, msecs_to_jiffies(2000));
-+
-+ queue_delayed_work(di->bat_monitor_wq, &di->bat_delay_work,
-+ msecs_to_jiffies(1000));
-+
-+ return 0;
-+}
-+
-+static void rk818_battery_shutdown(struct platform_device *dev)
-+{
-+ u8 cnt = 0;
-+ struct rk818_battery *di = platform_get_drvdata(dev);
-+
-+ cancel_delayed_work_sync(&di->bat_delay_work);
-+ cancel_delayed_work_sync(&di->calib_delay_work);
-+ rk818_bat_unregister_fb_notify(di);
-+ del_timer(&di->caltimer);
-+ if (base2sec(di->boot_base) < REBOOT_PERIOD_SEC)
-+ cnt = rk818_bat_check_reboot(di);
-+ else
-+ rk818_bat_save_reboot_cnt(di, 0);
-+
-+ BAT_INFO("shutdown: dl=%d rl=%d c=%d v=%d cap=%d f=%d ch=%d n=%d "
-+ "mode=%d rest=%d\n",
-+ di->dsoc, di->rsoc, di->current_avg, di->voltage_avg,
-+ di->remain_cap, di->fcc, rk818_bat_chrg_online(di), cnt,
-+ di->algo_rest_mode, di->algo_rest_val);
-+}
-+
-+static struct platform_driver rk818_battery_driver = {
-+ .probe = rk818_battery_probe,
-+ .suspend = rk818_battery_suspend,
-+ .resume = rk818_battery_resume,
-+ .shutdown = rk818_battery_shutdown,
-+ .driver = {
-+ .name = "rk818-battery",
-+ .of_match_table = rk818_battery_of_match,
-+ },
-+};
-+
-+static int __init battery_init(void)
-+{
-+ return platform_driver_register(&rk818_battery_driver);
-+}
-+fs_initcall_sync(battery_init);
-+
-+static void __exit battery_exit(void)
-+{
-+ platform_driver_unregister(&rk818_battery_driver);
-+}
-+module_exit(battery_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:rk818-battery");
-+MODULE_AUTHOR("chenjh");
-\ No newline at end of file
-diff --git a/drivers/power/supply/rk818_battery.h b/drivers/power/supply/rk818_battery.h
-new file mode 100644
-index 00000000..2f4430a
---- /dev/null
-+++ b/drivers/power/supply/rk818_battery.h
-@@ -0,0 +1,168 @@
-+/*
-+ * rk818_battery.h: fuel gauge driver structures
-+ *
-+ * Copyright (C) 2016 Rockchip Electronics Co., Ltd
-+ * Author: chenjh
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope 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 RK818_BATTERY
-+#define RK818_BATTERY
-+
-+/* RK818_INT_STS_MSK_REG2 */
-+#define PLUG_IN_MSK BIT(0)
-+#define PLUG_OUT_MSK BIT(1)
-+#define CHRG_CVTLMT_INT_MSK BIT(6)
-+
-+/* RK818_TS_CTRL_REG */
-+#define GG_EN BIT(7)
-+#define ADC_CUR_EN BIT(6)
-+#define ADC_TS1_EN BIT(5)
-+#define ADC_TS2_EN BIT(4)
-+#define TS1_CUR_MSK 0x03
-+
-+/* RK818_GGCON */
-+#define OCV_SAMP_MIN_MSK 0x0c
-+#define OCV_SAMP_8MIN (0x00 << 2)
-+
-+#define ADC_CAL_MIN_MSK 0x30
-+#define ADC_CAL_8MIN (0x00 << 4)
-+#define ADC_CUR_MODE BIT(1)
-+
-+/* RK818_GGSTS */
-+#define BAT_CON BIT(4)
-+#define RELAX_VOL1_UPD BIT(3)
-+#define RELAX_VOL2_UPD BIT(2)
-+#define RELAX_VOL12_UPD_MSK (RELAX_VOL1_UPD | RELAX_VOL2_UPD)
-+
-+/* RK818_SUP_STS_REG */
-+#define CHRG_STATUS_MSK 0x70
-+#define BAT_EXS BIT(7)
-+#define CHARGE_OFF (0x0 << 4)
-+#define DEAD_CHARGE (0x1 << 4)
-+#define TRICKLE_CHARGE (0x2 << 4)
-+#define CC_OR_CV (0x3 << 4)
-+#define CHARGE_FINISH (0x4 << 4)
-+#define USB_OVER_VOL (0x5 << 4)
-+#define BAT_TMP_ERR (0x6 << 4)
-+#define TIMER_ERR (0x7 << 4)
-+#define USB_VLIMIT_EN BIT(3)
-+#define USB_CLIMIT_EN BIT(2)
-+#define USB_EXIST BIT(1)
-+#define USB_EFF BIT(0)
-+
-+/* RK818_USB_CTRL_REG */
-+#define CHRG_CT_EN BIT(7)
-+#define FINISH_CUR_MSK 0xc0
-+#define TEMP_105C (0x02 << 2)
-+#define FINISH_100MA (0x00 << 6)
-+#define FINISH_150MA (0x01 << 6)
-+#define FINISH_200MA (0x02 << 6)
-+#define FINISH_250MA (0x03 << 6)
-+
-+/* RK818_CHRG_CTRL_REG3 */
-+#define CHRG_TERM_MODE_MSK BIT(5)
-+#define CHRG_TERM_ANA_SIGNAL (0 << 5)
-+#define CHRG_TERM_DIG_SIGNAL BIT(5)
-+#define CHRG_TIMER_CCCV_EN BIT(2)
-+#define CHRG_EN BIT(7)
-+
-+/* RK818_VB_MON_REG */
-+#define RK818_VBAT_LOW_3V0 0x02
-+#define RK818_VBAT_LOW_3V4 0x06
-+#define PLUG_IN_STS BIT(6)
-+
-+/* RK818_THERMAL_REG */
-+#define FB_TEMP_MSK 0x0c
-+#define HOTDIE_STS BIT(1)
-+
-+/* RK818_INT_STS_MSK_REG1 */
-+#define VB_LOW_INT_EN BIT(1)
-+
-+/* RK818_MISC_MARK_REG */
-+#define FG_INIT BIT(5)
-+#define FG_RESET_LATE BIT(4)
-+#define FG_RESET_NOW BIT(3)
-+#define ALGO_REST_MODE_MSK (0xc0)
-+#define ALGO_REST_MODE_SHIFT 6
-+
-+/* bit shift */
-+#define FB_TEMP_SHIFT 2
-+
-+/* parse ocv table param */
-+#define TIMER_MS_COUNTS 1000
-+#define MAX_PERCENTAGE 100
-+#define MAX_INTERPOLATE 1000
-+#define MAX_INT 0x7FFF
-+
-+#define DRIVER_VERSION "7.1"
-+
-+struct battery_platform_data {
-+ u32 *ocv_table;
-+ u32 *zero_table;
-+ u32 *ntc_table;
-+ u32 ocv_size;
-+ u32 max_chrg_voltage;
-+ u32 ntc_size;
-+ int ntc_degree_from;
-+ u32 pwroff_vol;
-+ u32 monitor_sec;
-+ u32 zero_algorithm_vol;
-+ u32 zero_reserve_dsoc;
-+ u32 bat_res;
-+ u32 design_capacity;
-+ u32 design_qmax;
-+ u32 sleep_enter_current;
-+ u32 sleep_exit_current;
-+ u32 max_soc_offset;
-+ u32 sample_res;
-+ u32 bat_mode;
-+ u32 fb_temp;
-+ u32 energy_mode;
-+ u32 cccv_hour;
-+ u32 ntc_uA;
-+ u32 ntc_factor;
-+};
-+
-+enum work_mode {
-+ MODE_ZERO = 0,
-+ MODE_FINISH,
-+ MODE_SMOOTH_CHRG,
-+ MODE_SMOOTH_DISCHRG,
-+ MODE_SMOOTH,
-+};
-+
-+enum bat_mode {
-+ MODE_BATTARY = 0,
-+ MODE_VIRTUAL,
-+};
-+
-+static const u16 feedback_temp_array[] = {
-+ 85, 95, 105, 115
-+};
-+
-+static const u16 chrg_vol_sel_array[] = {
-+ 4050, 4100, 4150, 4200, 4250, 4300, 4350
-+};
-+
-+static const u16 chrg_cur_sel_array[] = {
-+ 1000, 1200, 1400, 1600, 1800, 2000, 2250, 2400, 2600, 2800, 3000
-+};
-+
-+static const u16 chrg_cur_input_array[] = {
-+ 450, 80, 850, 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000
-+};
-+
-+void kernel_power_off(void);
-+int rk818_bat_temp_notifier_register(struct notifier_block *nb);
-+int rk818_bat_temp_notifier_unregister(struct notifier_block *nb);
-+
-+#endif
-\ No newline at end of file
-diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
-index 2ec0520..5e33996 100644
---- a/include/linux/mfd/rk808.h
-+++ b/include/linux/mfd/rk808.h
-@@ -138,6 +138,8 @@ enum rk818_reg {
- RK818_ID_OTG_SWITCH,
- };
-
-+#define RK818_VB_MON_REG 0x21
-+#define RK818_THERMAL_REG 0x22
- #define RK818_DCDC_EN_REG 0x23
- #define RK818_LDO_EN_REG 0x24
- #define RK818_SLEEP_SET_OFF_REG1 0x25
-@@ -184,13 +186,90 @@ enum rk818_reg {
- #define RK818_INT_STS_REG2 0x4e
- #define RK818_INT_STS_MSK_REG2 0x4f
- #define RK818_IO_POL_REG 0x50
-+#define RK818_OTP_VDD_EN_REG 0x51
- #define RK818_H5V_EN_REG 0x52
- #define RK818_SLEEP_SET_OFF_REG3 0x53
- #define RK818_BOOST_LDO9_ON_VSEL_REG 0x54
- #define RK818_BOOST_LDO9_SLP_VSEL_REG 0x55
- #define RK818_BOOST_CTRL_REG 0x56
--#define RK818_DCDC_ILMAX 0x90
-+#define RK818_DCDC_ILMAX_REG 0x90
-+#define RK818_CHRG_COMP_REG 0x9a
-+#define RK818_SUP_STS_REG 0xa0
- #define RK818_USB_CTRL_REG 0xa1
-+#define RK818_CHRG_CTRL_REG1 0xa3
-+#define RK818_CHRG_CTRL_REG2 0xa4
-+#define RK818_CHRG_CTRL_REG3 0xa5
-+#define RK818_BAT_CTRL_REG 0xa6
-+#define RK818_BAT_HTS_TS1_REG 0xa8
-+#define RK818_BAT_LTS_TS1_REG 0xa9
-+#define RK818_BAT_HTS_TS2_REG 0xaa
-+#define RK818_BAT_LTS_TS2_REG 0xab
-+#define RK818_TS_CTRL_REG 0xac
-+#define RK818_ADC_CTRL_REG 0xad
-+#define RK818_ON_SOURCE_REG 0xae
-+#define RK818_OFF_SOURCE_REG 0xaf
-+#define RK818_GGCON_REG 0xb0
-+#define RK818_GGSTS_REG 0xb1
-+#define RK818_FRAME_SMP_INTERV_REG 0xb2
-+#define RK818_AUTO_SLP_CUR_THR_REG 0xb3
-+#define RK818_GASCNT_CAL_REG3 0xb4
-+#define RK818_GASCNT_CAL_REG2 0xb5
-+#define RK818_GASCNT_CAL_REG1 0xb6
-+#define RK818_GASCNT_CAL_REG0 0xb7
-+#define RK818_GASCNT3_REG 0xb8
-+#define RK818_GASCNT2_REG 0xb9
-+#define RK818_GASCNT1_REG 0xba
-+#define RK818_GASCNT0_REG 0xbb
-+#define RK818_BAT_CUR_AVG_REGH 0xbc
-+#define RK818_BAT_CUR_AVG_REGL 0xbd
-+#define RK818_TS1_ADC_REGH 0xbe
-+#define RK818_TS1_ADC_REGL 0xbf
-+#define RK818_TS2_ADC_REGH 0xc0
-+#define RK818_TS2_ADC_REGL 0xc1
-+#define RK818_BAT_OCV_REGH 0xc2
-+#define RK818_BAT_OCV_REGL 0xc3
-+#define RK818_BAT_VOL_REGH 0xc4
-+#define RK818_BAT_VOL_REGL 0xc5
-+#define RK818_RELAX_ENTRY_THRES_REGH 0xc6
-+#define RK818_RELAX_ENTRY_THRES_REGL 0xc7
-+#define RK818_RELAX_EXIT_THRES_REGH 0xc8
-+#define RK818_RELAX_EXIT_THRES_REGL 0xc9
-+#define RK818_RELAX_VOL1_REGH 0xca
-+#define RK818_RELAX_VOL1_REGL 0xcb
-+#define RK818_RELAX_VOL2_REGH 0xcc
-+#define RK818_RELAX_VOL2_REGL 0xcd
-+#define RK818_BAT_CUR_R_CALC_REGH 0xce
-+#define RK818_BAT_CUR_R_CALC_REGL 0xcf
-+#define RK818_BAT_VOL_R_CALC_REGH 0xd0
-+#define RK818_BAT_VOL_R_CALC_REGL 0xd1
-+#define RK818_CAL_OFFSET_REGH 0xd2
-+#define RK818_CAL_OFFSET_REGL 0xd3
-+#define RK818_NON_ACT_TIMER_CNT_REG 0xd4
-+#define RK818_VCALIB0_REGH 0xd5
-+#define RK818_VCALIB0_REGL 0xd6
-+#define RK818_VCALIB1_REGH 0xd7
-+#define RK818_VCALIB1_REGL 0xd8
-+#define RK818_IOFFSET_REGH 0xdd
-+#define RK818_IOFFSET_REGL 0xde
-+#define RK818_SOC_REG 0xe0
-+#define RK818_REMAIN_CAP_REG3 0xe1
-+#define RK818_REMAIN_CAP_REG2 0xe2
-+#define RK818_REMAIN_CAP_REG1 0xe3
-+#define RK818_REMAIN_CAP_REG0 0xe4
-+#define RK818_UPDAT_LEVE_REG 0xe5
-+#define RK818_NEW_FCC_REG3 0xe6
-+#define RK818_NEW_FCC_REG2 0xe7
-+#define RK818_NEW_FCC_REG1 0xe8
-+#define RK818_NEW_FCC_REG0 0xe9
-+#define RK818_NON_ACT_TIMER_CNT_SAVE_REG 0xea
-+#define RK818_OCV_VOL_VALID_REG 0xeb
-+#define RK818_REBOOT_CNT_REG 0xec
-+#define RK818_POFFSET_REG 0xed
-+#define RK818_MISC_MARK_REG 0xee
-+#define RK818_HALT_CNT_REG 0xef
-+#define RK818_CALC_REST_REGH 0xf0
-+#define RK818_CALC_REST_REGL 0xf1
-+#define RK818_SAVE_DATA19 0xf2
-
- #define RK818_H5V_EN BIT(0)
- #define RK818_REF_RDY_CTRL BIT(1)
diff --git a/sys-kernel/pinephone-pro-sources/files/0012-bootsplash.patch b/sys-kernel/pinephone-pro-sources/files/0012-bootsplash.patch
deleted file mode 100644
index 5d8ea1f..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0012-bootsplash.patch
+++ /dev/null
@@ -1,511 +0,0 @@
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 7ffac272434e..ddff07cd794c 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -2715,6 +2715,7 @@ F: drivers/video/fbdev/core/bootsplash*.*
- F: drivers/video/fbdev/core/dummycon.c
- F: include/linux/bootsplash.h
- F: include/uapi/linux/bootsplash_file.h
-+F: tools/bootsplash/*
-
- BPF (Safe dynamic programs and tools)
- M: Alexei Starovoitov
-diff --git a/tools/bootsplash/.gitignore b/tools/bootsplash/.gitignore
-new file mode 100644
-index 000000000000..091b99a17567
---- /dev/null
-+++ b/tools/bootsplash/.gitignore
-@@ -0,0 +1 @@
-+bootsplash-packer
-diff --git a/tools/bootsplash/Makefile b/tools/bootsplash/Makefile
-new file mode 100644
-index 000000000000..0ad8e8a84942
---- /dev/null
-+++ b/tools/bootsplash/Makefile
-@@ -0,0 +1,9 @@
-+CC := $(CROSS_COMPILE)gcc
-+CFLAGS := -I../../usr/include
-+
-+PROGS := bootsplash-packer
-+
-+all: $(PROGS)
-+
-+clean:
-+ rm -fr $(PROGS)
-diff --git a/tools/bootsplash/bootsplash-packer.c b/tools/bootsplash/bootsplash-packer.c
-new file mode 100644
-index 000000000000..ffb6a8b69885
---- /dev/null
-+++ b/tools/bootsplash/bootsplash-packer.c
-@@ -0,0 +1,471 @@
-+/*
-+ * Kernel based bootsplash.
-+ *
-+ * (Splash file packer tool)
-+ *
-+ * Authors:
-+ * Max Staudt
-+ *
-+ * SPDX-License-Identifier: GPL-2.0
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include
-+
-+
-+static void print_help(char *progname)
-+{
-+ printf("Usage: %s [OPTIONS] outfile\n", progname);
-+ printf("\n"
-+ "Options, executed in order given:\n"
-+ " -h, --help Print this help message\n"
-+ "\n"
-+ " --bg_red Background color (red part)\n"
-+ " --bg_green Background color (green part)\n"
-+ " --bg_blue Background color (blue part)\n"
-+ " --bg_reserved (do not use)\n"
-+ " --frame_ms Minimum milliseconds between animation steps\n"
-+ "\n"
-+ " --picture Start describing the next picture\n"
-+ " --pic_width Picture width in pixels\n"
-+ " --pic_height Picture height in pixels\n"
-+ " --pic_position Coarse picture placement:\n"
-+ " 0x00 - Top left\n"
-+ " 0x01 - Top\n"
-+ " 0x02 - Top right\n"
-+ " 0x03 - Right\n"
-+ " 0x04 - Bottom right\n"
-+ " 0x05 - Bottom\n"
-+ " 0x06 - Bottom left\n"
-+ " 0x07 - Left\n"
-+ "\n"
-+ " Flags:\n"
-+ " 0x10 - Calculate offset from corner towards center,\n"
-+ " rather than from center towards corner\n"
-+ " --pic_position_offset Distance from base position in pixels\n"
-+ " --pic_anim_type Animation type:\n"
-+ " 0 - None\n"
-+ " 1 - Forward loop\n"
-+ " --pic_anim_loop Loop point for animation\n"
-+ "\n"
-+ " --blob Include next data stream\n"
-+ " --blob_type Type of data\n"
-+ " --blob_picture_id Picture to associate this blob with, starting at 0\n"
-+ " (default: number of last --picture)\n"
-+ "\n");
-+ printf("This tool will write %s files.\n\n",
-+#if __BYTE_ORDER == __BIG_ENDIAN
-+ "Big Endian (BE)");
-+#elif __BYTE_ORDER == __LITTLE_ENDIAN
-+ "Little Endian (LE)");
-+#else
-+#error
-+#endif
-+}
-+
-+
-+struct blob_entry {
-+ struct blob_entry *next;
-+
-+ char *fn;
-+
-+ struct splash_blob_header header;
-+};
-+
-+
-+static void dump_file_header(struct splash_file_header *h)
-+{
-+ printf(" --- File header ---\n");
-+ printf("\n");
-+ printf(" version: %5u\n", h->version);
-+ printf("\n");
-+ printf(" bg_red: %5u\n", h->bg_red);
-+ printf(" bg_green: %5u\n", h->bg_green);
-+ printf(" bg_blue: %5u\n", h->bg_blue);
-+ printf(" bg_reserved: %5u\n", h->bg_reserved);
-+ printf("\n");
-+ printf(" num_blobs: %5u\n", h->num_blobs);
-+ printf(" num_pics: %5u\n", h->num_pics);
-+ printf("\n");
-+ printf(" frame_ms: %5u\n", h->frame_ms);
-+ printf("\n");
-+}
-+
-+static void dump_pic_header(struct splash_pic_header *ph)
-+{
-+ printf(" --- Picture header ---\n");
-+ printf("\n");
-+ printf(" width: %5u\n", ph->width);
-+ printf(" height: %5u\n", ph->height);
-+ printf("\n");
-+ printf(" num_blobs: %5u\n", ph->num_blobs);
-+ printf("\n");
-+ printf(" position: %0x3x\n", ph->position);
-+ printf(" position_offset: %5u\n", ph->position_offset);
-+ printf("\n");
-+ printf(" anim_type: %5u\n", ph->anim_type);
-+ printf(" anim_loop: %5u\n", ph->anim_loop);
-+ printf("\n");
-+}
-+
-+static void dump_blob(struct blob_entry *b)
-+{
-+ printf(" --- Blob header ---\n");
-+ printf("\n");
-+ printf(" length: %7u\n", b->header.length);
-+ printf(" type: %7u\n", b->header.type);
-+ printf("\n");
-+ printf(" picture_id: %7u\n", b->header.picture_id);
-+ printf("\n");
-+}
-+
-+
-+#define OPT_MAX(var, max) \
-+ do { \
-+ if ((var) > max) { \
-+ fprintf(stderr, "--%s: Invalid value\n", \
-+ long_options[option_index].name); \
-+ break; \
-+ } \
-+ } while (0)
-+
-+static struct option long_options[] = {
-+ {"help", 0, 0, 'h'},
-+ {"bg_red", 1, 0, 10001},
-+ {"bg_green", 1, 0, 10002},
-+ {"bg_blue", 1, 0, 10003},
-+ {"bg_reserved", 1, 0, 10004},
-+ {"frame_ms", 1, 0, 10005},
-+ {"picture", 0, 0, 20000},
-+ {"pic_width", 1, 0, 20001},
-+ {"pic_height", 1, 0, 20002},
-+ {"pic_position", 1, 0, 20003},
-+ {"pic_position_offset", 1, 0, 20004},
-+ {"pic_anim_type", 1, 0, 20005},
-+ {"pic_anim_loop", 1, 0, 20006},
-+ {"blob", 1, 0, 30000},
-+ {"blob_type", 1, 0, 30001},
-+ {"blob_picture_id", 1, 0, 30002},
-+ {NULL, 0, NULL, 0}
-+};
-+
-+
-+int main(int argc, char **argv)
-+{
-+ FILE *of;
-+ char *ofn;
-+ int c;
-+ int option_index = 0;
-+
-+ unsigned long ul;
-+ struct splash_file_header fh = {};
-+ struct splash_pic_header ph[255];
-+ struct blob_entry *blob_first = NULL;
-+ struct blob_entry *blob_last = NULL;
-+ struct blob_entry *blob_cur = NULL;
-+
-+ if (argc < 2) {
-+ print_help(argv[0]);
-+ return EXIT_FAILURE;
-+ }
-+
-+
-+ /* Parse and and execute user commands */
-+ while ((c = getopt_long(argc, argv, "h",
-+ long_options, &option_index)) != -1) {
-+ switch (c) {
-+ case 10001: /* bg_red */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 255);
-+ fh.bg_red = ul;
-+ break;
-+ case 10002: /* bg_green */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 255);
-+ fh.bg_green = ul;
-+ break;
-+ case 10003: /* bg_blue */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 255);
-+ fh.bg_blue = ul;
-+ break;
-+ case 10004: /* bg_reserved */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 255);
-+ fh.bg_reserved = ul;
-+ break;
-+ case 10005: /* frame_ms */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 65535);
-+ fh.frame_ms = ul;
-+ break;
-+
-+
-+ case 20000: /* picture */
-+ if (fh.num_pics >= 255) {
-+ fprintf(stderr, "--%s: Picture array full\n",
-+ long_options[option_index].name);
-+ break;
-+ }
-+
-+ fh.num_pics++;
-+ break;
-+
-+ case 20001: /* pic_width */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 65535);
-+ ph[fh.num_pics - 1].width = ul;
-+ break;
-+
-+ case 20002: /* pic_height */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 65535);
-+ ph[fh.num_pics - 1].height = ul;
-+ break;
-+
-+ case 20003: /* pic_position */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 255);
-+ ph[fh.num_pics - 1].position = ul;
-+ break;
-+
-+ case 20004: /* pic_position_offset */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 255);
-+ ph[fh.num_pics - 1].position_offset = ul;
-+ break;
-+
-+ case 20005: /* pic_anim_type */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 255);
-+ ph[fh.num_pics - 1].anim_type = ul;
-+ break;
-+
-+ case 20006: /* pic_anim_loop */
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 255);
-+ ph[fh.num_pics - 1].anim_loop = ul;
-+ break;
-+
-+
-+ case 30000: /* blob */
-+ if (fh.num_blobs >= 65535) {
-+ fprintf(stderr, "--%s: Blob array full\n",
-+ long_options[option_index].name);
-+ break;
-+ }
-+
-+ blob_cur = calloc(1, sizeof(struct blob_entry));
-+ if (!blob_cur) {
-+ fprintf(stderr, "--%s: Out of memory\n",
-+ long_options[option_index].name);
-+ break;
-+ }
-+
-+ blob_cur->fn = optarg;
-+ if (fh.num_pics)
-+ blob_cur->header.picture_id = fh.num_pics - 1;
-+
-+ if (!blob_first)
-+ blob_first = blob_cur;
-+ if (blob_last)
-+ blob_last->next = blob_cur;
-+ blob_last = blob_cur;
-+ fh.num_blobs++;
-+ break;
-+
-+ case 30001: /* blob_type */
-+ if (!blob_cur) {
-+ fprintf(stderr, "--%s: No blob selected\n",
-+ long_options[option_index].name);
-+ break;
-+ }
-+
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 255);
-+ blob_cur->header.type = ul;
-+ break;
-+
-+ case 30002: /* blob_picture_id */
-+ if (!blob_cur) {
-+ fprintf(stderr, "--%s: No blob selected\n",
-+ long_options[option_index].name);
-+ break;
-+ }
-+
-+ ul = strtoul(optarg, NULL, 0);
-+ OPT_MAX(ul, 255);
-+ blob_cur->header.picture_id = ul;
-+ break;
-+
-+
-+
-+ case 'h':
-+ case '?':
-+ default:
-+ print_help(argv[0]);
-+ goto EXIT;
-+ } /* switch (c) */
-+ } /* while ((c = getopt_long(...)) != -1) */
-+
-+ /* Consume and drop lone arguments */
-+ while (optind < argc) {
-+ ofn = argv[optind];
-+ optind++;
-+ }
-+
-+
-+ /* Read file lengths */
-+ for (blob_cur = blob_first; blob_cur; blob_cur = blob_cur->next) {
-+ FILE *f;
-+ long pos;
-+ int i;
-+
-+ if (!blob_cur->fn)
-+ continue;
-+
-+ f = fopen(blob_cur->fn, "rb");
-+ if (!f)
-+ goto ERR_FILE_LEN;
-+
-+ if (fseek(f, 0, SEEK_END))
-+ goto ERR_FILE_LEN;
-+
-+ pos = ftell(f);
-+ if (pos < 0 || pos > (1 << 30))
-+ goto ERR_FILE_LEN;
-+
-+ blob_cur->header.length = pos;
-+
-+ fclose(f);
-+ continue;
-+
-+ERR_FILE_LEN:
-+ fprintf(stderr, "Error getting file length (or too long): %s\n",
-+ blob_cur->fn);
-+ if (f)
-+ fclose(f);
-+ continue;
-+ }
-+
-+
-+ /* Set magic headers */
-+#if __BYTE_ORDER == __BIG_ENDIAN
-+ memcpy(&fh.id[0], BOOTSPLASH_MAGIC_BE, 16);
-+#elif __BYTE_ORDER == __LITTLE_ENDIAN
-+ memcpy(&fh.id[0], BOOTSPLASH_MAGIC_LE, 16);
-+#else
-+#error
-+#endif
-+ fh.version = BOOTSPLASH_VERSION;
-+
-+ /* Set blob counts */
-+ for (blob_cur = blob_first; blob_cur; blob_cur = blob_cur->next) {
-+ if (blob_cur->header.picture_id < fh.num_pics)
-+ ph[blob_cur->header.picture_id].num_blobs++;
-+ }
-+
-+
-+ /* Dump structs */
-+ dump_file_header(&fh);
-+
-+ for (ul = 0; ul < fh.num_pics; ul++)
-+ dump_pic_header(&ph[ul]);
-+
-+ for (blob_cur = blob_first; blob_cur; blob_cur = blob_cur->next)
-+ dump_blob(blob_cur);
-+
-+
-+ /* Write to file */
-+ printf("Writing splash to file: %s\n", ofn);
-+ of = fopen(ofn, "wb");
-+ if (!of)
-+ goto ERR_WRITING;
-+
-+ if (fwrite(&fh, sizeof(struct splash_file_header), 1, of) != 1)
-+ goto ERR_WRITING;
-+
-+ for (ul = 0; ul < fh.num_pics; ul++) {
-+ if (fwrite(&ph[ul], sizeof(struct splash_pic_header), 1, of)
-+ != 1)
-+ goto ERR_WRITING;
-+ }
-+
-+ blob_cur = blob_first;
-+ while (blob_cur) {
-+ struct blob_entry *blob_old = blob_cur;
-+ FILE *f;
-+ char *buf[256];
-+ uint32_t left;
-+
-+ if (fwrite(&blob_cur->header,
-+ sizeof(struct splash_blob_header), 1, of) != 1)
-+ goto ERR_WRITING;
-+
-+ if (!blob_cur->header.length || !blob_cur->fn)
-+ continue;
-+
-+ f = fopen(blob_cur->fn, "rb");
-+ if (!f)
-+ goto ERR_FILE_COPY;
-+
-+ left = blob_cur->header.length;
-+ while (left >= sizeof(buf)) {
-+ if (fread(buf, sizeof(buf), 1, f) != 1)
-+ goto ERR_FILE_COPY;
-+ if (fwrite(buf, sizeof(buf), 1, of) != 1)
-+ goto ERR_FILE_COPY;
-+ left -= sizeof(buf);
-+ }
-+ if (left) {
-+ if (fread(buf, left, 1, f) != 1)
-+ goto ERR_FILE_COPY;
-+ if (fwrite(buf, left, 1, of) != 1)
-+ goto ERR_FILE_COPY;
-+ }
-+
-+ /* Pad data stream to 16 bytes */
-+ if (left % 16) {
-+ if (fwrite("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
-+ 16 - (left % 16), 1, of) != 1)
-+ goto ERR_FILE_COPY;
-+ }
-+
-+ fclose(f);
-+ blob_cur = blob_cur->next;
-+ free(blob_old);
-+ continue;
-+
-+ERR_FILE_COPY:
-+ if (f)
-+ fclose(f);
-+ goto ERR_WRITING;
-+ }
-+
-+ fclose(of);
-+
-+EXIT:
-+ return EXIT_SUCCESS;
-+
-+
-+ERR_WRITING:
-+ fprintf(stderr, "Error writing splash.\n");
-+ fprintf(stderr, "The output file is probably corrupt.\n");
-+ if (of)
-+ fclose(of);
-+
-+ while (blob_cur) {
-+ struct blob_entry *blob_old = blob_cur;
-+
-+ blob_cur = blob_cur->next;
-+ free(blob_old);
-+ }
-+
-+ return EXIT_FAILURE;
-+}
diff --git a/sys-kernel/pinephone-pro-sources/files/0012-power-supply-rk818-battery-Use-a-more-propper-compat.patch b/sys-kernel/pinephone-pro-sources/files/0012-power-supply-rk818-battery-Use-a-more-propper-compat.patch
deleted file mode 100644
index fd97202..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0012-power-supply-rk818-battery-Use-a-more-propper-compat.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 7 Nov 2021 19:30:07 +0100
-Subject: [PATCH 13/36] power: supply: rk818-battery: Use a more propper
- compatible string
-
-Prefix with vendor name.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/mfd/rk808.c | 2 +-
- drivers/power/supply/rk818_battery.c | 4 ++--
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
-index 7d1f000..a99fec0 100644
---- a/drivers/mfd/rk808.c
-+++ b/drivers/mfd/rk808.c
-@@ -205,7 +205,7 @@ static const struct mfd_cell rk817s[] = {
- static const struct mfd_cell rk818s[] = {
- { .name = "rk808-clkout", },
- { .name = "rk808-regulator", },
-- { .name = "rk818-battery", .of_compatible = "rk818-battery", },
-+ { .name = "rk818-battery", .of_compatible = "rockchip,rk818-battery", },
- {
- .name = "rk808-rtc",
- .num_resources = ARRAY_SIZE(rtc_resources),
-diff --git a/drivers/power/supply/rk818_battery.c b/drivers/power/supply/rk818_battery.c
-index f09f456..665f043 100644
---- a/drivers/power/supply/rk818_battery.c
-+++ b/drivers/power/supply/rk818_battery.c
-@@ -3339,7 +3339,7 @@ static int rk818_bat_parse_dt(struct rk818_battery *di)
- #endif
-
- static const struct of_device_id rk818_battery_of_match[] = {
-- {.compatible = "rk818-battery",},
-+ { .compatible = "rockchip,rk818-battery", },
- { },
- };
-
-@@ -3565,4 +3565,4 @@ module_exit(battery_exit);
-
- MODULE_LICENSE("GPL");
- MODULE_ALIAS("platform:rk818-battery");
--MODULE_AUTHOR("chenjh");
-\ No newline at end of file
-+MODULE_AUTHOR("chenjh");
diff --git a/sys-kernel/pinephone-pro-sources/files/0013-power-supply-core-Don-t-ignore-max_current-of-0-when.patch b/sys-kernel/pinephone-pro-sources/files/0013-power-supply-core-Don-t-ignore-max_current-of-0-when.patch
deleted file mode 100644
index 69f1677..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0013-power-supply-core-Don-t-ignore-max_current-of-0-when.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 14 Nov 2021 21:24:05 +0100
-Subject: [PATCH 14/36] power: supply: core: Don't ignore max_current of 0
- when setting current limit
-
-If we ignore current limit of 0, the dependent power source will not
-set input current limit to that value when the supplier changes max
-current to 0. This may happen when USB power is disconnected from the
-device.
-
-On next connection, the dependent power supply will start consuming
-power at the previously set limit even before the PD/BC1.2 power
-negotiation has a chance to complete.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/power/supply/power_supply_core.c | 47 ++++++++++++++------------------
- 1 file changed, 20 insertions(+), 27 deletions(-)
-
-diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
-index 6093754..1c5be0d 100644
---- a/drivers/power/supply/power_supply_core.c
-+++ b/drivers/power/supply/power_supply_core.c
-@@ -375,41 +375,34 @@ int power_supply_is_system_supplied(void)
- }
- EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
-
--static int __power_supply_get_supplier_max_current(struct device *dev,
-- void *data)
--{
-- union power_supply_propval ret = {0,};
-- struct power_supply *epsy = dev_get_drvdata(dev);
-- struct power_supply *psy = data;
--
-- if (__power_supply_is_supplied_by(epsy, psy))
-- if (!epsy->desc->get_property(epsy,
-- POWER_SUPPLY_PROP_CURRENT_MAX,
-- &ret))
-- return ret.intval;
--
-- return 0;
--}
--
- int power_supply_set_input_current_limit_from_supplier(struct power_supply *psy)
- {
- union power_supply_propval val = {0,};
-- int curr;
-+ struct class_dev_iter iter;
-+ struct power_supply *epsy;
-+ struct device *dev;
-+ int ret;
-
- if (!psy->desc->set_property)
- return -EINVAL;
-
-- /*
-- * This function is not intended for use with a supply with multiple
-- * suppliers, we simply pick the first supply to report a non 0
-- * max-current.
-- */
-- curr = class_for_each_device(power_supply_class, NULL, psy,
-- __power_supply_get_supplier_max_current);
-- if (curr <= 0)
-- return (curr == 0) ? -ENODEV : curr;
-+ class_dev_iter_init(&iter, power_supply_class, NULL, NULL);
-+ while ((dev = class_dev_iter_next(&iter))) {
-+ epsy = dev_get_drvdata(dev);
-+
-+ if (!__power_supply_is_supplied_by(epsy, psy))
-+ continue;
-
-- val.intval = curr;
-+ ret = epsy->desc->get_property(epsy,
-+ POWER_SUPPLY_PROP_CURRENT_MAX,
-+ &val);
-+ if (!ret)
-+ break;
-+ }
-+ class_dev_iter_exit(&iter);
-+
-+ if (ret)
-+ return ret;
-
- return psy->desc->set_property(psy,
- POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
diff --git a/sys-kernel/pinephone-pro-sources/files/0014-power-supply-rk818-charger-Implement-charger-driver-.patch b/sys-kernel/pinephone-pro-sources/files/0014-power-supply-rk818-charger-Implement-charger-driver-.patch
deleted file mode 100644
index 232c70e..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0014-power-supply-rk818-charger-Implement-charger-driver-.patch
+++ /dev/null
@@ -1,699 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 7 Nov 2021 20:09:02 +0100
-Subject: [PATCH 15/36] power: supply: rk818-charger: Implement charger driver
- for RK818 PMIC
-
-For now this driver is just meant to watch Type-C power supply
-and apply current limits to RK818, to not overload the Type-C
-partner.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/mfd/rk808.c | 1 +
- drivers/power/supply/Kconfig | 8 +
- drivers/power/supply/Makefile | 1 +
- drivers/power/supply/rk818_charger.c | 637 +++++++++++++++++++++++++++++++++++
- 4 files changed, 647 insertions(+)
- create mode 100644 drivers/power/supply/rk818_charger.c
-
-diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
-index a99fec0..75d18de 100644
---- a/drivers/mfd/rk808.c
-+++ b/drivers/mfd/rk808.c
-@@ -206,6 +206,7 @@ static const struct mfd_cell rk818s[] = {
- { .name = "rk808-clkout", },
- { .name = "rk808-regulator", },
- { .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),
-diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
-index f5d4434..6bf0834 100644
---- a/drivers/power/supply/Kconfig
-+++ b/drivers/power/supply/Kconfig
-@@ -862,4 +862,12 @@ config BATTERY_RK818
- If you say yes here you will get support for the battery of RK818 PMIC.
- This driver can give support for Rk818 Battery Charge Interface.
-
-+config CHARGER_RK818
-+ bool "RK818 Charger driver"
-+ depends on MFD_RK808
-+ default n
-+ help
-+ If you say yes here you will get support for the charger of RK818 PMIC.
-+ This driver can give support for Rk818 Charger Interface.
-+
- endif # POWER_SUPPLY
-diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
-index 1c725ee..3a1526f 100644
---- a/drivers/power/supply/Makefile
-+++ b/drivers/power/supply/Makefile
-@@ -105,3 +105,4 @@ obj-$(CONFIG_BATTERY_ACER_A500) += acer_a500_battery.o
- obj-$(CONFIG_BATTERY_SURFACE) += surface_battery.o
- obj-$(CONFIG_CHARGER_SURFACE) += surface_charger.o
- obj-$(CONFIG_BATTERY_RK818) += rk818_battery.o
-+obj-$(CONFIG_CHARGER_RK818) += rk818_charger.o
-diff --git a/drivers/power/supply/rk818_charger.c b/drivers/power/supply/rk818_charger.c
-new file mode 100644
-index 00000000..097f30b
---- /dev/null
-+++ b/drivers/power/supply/rk818_charger.c
-@@ -0,0 +1,637 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * rk818 usb power driver
-+ *
-+ * Copyright (c) 2021 Ondřej Jirman
-+ */
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#define RK818_CHG_STS_MASK (7u << 4) /* charger status */
-+#define RK818_CHG_STS_NONE (0u << 4)
-+#define RK818_CHG_STS_WAKEUP_CUR (1u << 4)
-+#define RK818_CHG_STS_TRICKLE_CUR (2u << 4)
-+#define RK818_CHG_STS_CC_OR_CV (3u << 4)
-+#define RK818_CHG_STS_TERMINATED (4u << 4)
-+#define RK818_CHG_STS_USB_OV (5u << 4)
-+#define RK818_CHG_STS_BAT_TEMP_FAULT (6u << 4)
-+#define RK818_CHG_STS_TIMEOUT (7u << 4)
-+
-+/* RK818_SUP_STS_REG */
-+#define RK818_SUP_STS_USB_VLIM_EN BIT(3) /* input voltage limit enable */
-+#define RK818_SUP_STS_USB_ILIM_EN BIT(2) /* input current limit enable */
-+#define RK818_SUP_STS_USB_EXS BIT(1) /* USB power connected */
-+#define RK818_SUP_STS_USB_EFF BIT(0) /* USB fault */
-+
-+/* RK818_USB_CTRL_REG */
-+#define RK818_USB_CTRL_USB_ILIM_MASK (0xfu)
-+#define RK818_USB_CTRL_USB_CHG_SD_VSEL_OFFSET 4
-+#define RK818_USB_CTRL_USB_CHG_SD_VSEL_MASK (0x7u << 4)
-+
-+/* RK818_CHRG_CTRL_REG1 */
-+#define RK818_CHRG_CTRL_REG1_CHRG_EN BIT(7)
-+#define RK818_CHRG_CTRL_REG1_CHRG_VOL_SEL_OFFSET 4
-+#define RK818_CHRG_CTRL_REG1_CHRG_VOL_SEL_MASK (0x7u << 4)
-+#define RK818_CHRG_CTRL_REG1_CHRG_CUR_SEL_OFFSET 0
-+#define RK818_CHRG_CTRL_REG1_CHRG_CUR_SEL_MASK (0xfu << 0)
-+
-+/* RK818_CHRG_CTRL_REG3 */
-+#define RK818_CHRG_CTRL_REG3_CHRG_TERM_DIGITAL BIT(5)
-+
-+struct rk818_charger {
-+ struct device *dev;
-+ struct rk808 *rk818;
-+ struct regmap *regmap;
-+
-+ struct power_supply *usb_psy;
-+ struct power_supply *charger_psy;
-+};
-+
-+// {{{ USB supply
-+
-+static int rk818_usb_set_input_current_max(struct rk818_charger *cg,
-+ int val)
-+{
-+ int ret;
-+ unsigned reg;
-+
-+ if (val < 450000)
-+ reg = 1;
-+ else if (val < 850000)
-+ reg = 0;
-+ else if (val < 1000000)
-+ reg = 2;
-+ else if (val < 3000000)
-+ reg = 3 + (val - 1000000) / 250000;
-+ else
-+ reg = 11;
-+
-+ ret = regmap_update_bits(cg->regmap, RK818_USB_CTRL_REG,
-+ RK818_USB_CTRL_USB_ILIM_MASK, reg);
-+ if (ret)
-+ dev_err(cg->dev,
-+ "USB input current limit setting failed (%d)\n", ret);
-+
-+ return ret;
-+}
-+
-+static int rk818_usb_get_input_current_max(struct rk818_charger *cg,
-+ int *val)
-+{
-+ unsigned reg;
-+ int ret;
-+
-+ ret = regmap_read(cg->regmap, RK818_USB_CTRL_REG, ®);
-+ if (ret) {
-+ dev_err(cg->dev,
-+ "USB input current limit getting failed (%d)\n", ret);
-+ return ret;
-+ }
-+
-+ reg &= RK818_USB_CTRL_USB_ILIM_MASK;
-+ if (reg == 0)
-+ *val = 450000;
-+ else if (reg == 1)
-+ *val = 80000;
-+ else if (reg == 2)
-+ *val = 850000;
-+ else if (reg < 11)
-+ *val = 1000000 + (reg - 3) * 250000;
-+ else
-+ *val = 3000000;
-+
-+ return 0;
-+}
-+
-+static int rk818_usb_set_input_voltage_min(struct rk818_charger *cg,
-+ int val)
-+{
-+ unsigned reg;
-+ int ret;
-+
-+ if (val < 2780000)
-+ reg = 0;
-+ else if (val < 3270000)
-+ reg = (val - 2780000) / 70000;
-+ else
-+ reg = 7;
-+
-+ ret = regmap_update_bits(cg->regmap, RK818_USB_CTRL_REG,
-+ RK818_USB_CTRL_USB_CHG_SD_VSEL_MASK,
-+ reg << RK818_USB_CTRL_USB_CHG_SD_VSEL_OFFSET);
-+ if (ret)
-+ dev_err(cg->dev,
-+ "USB input voltage limit setting failed (%d)\n", ret);
-+
-+ return ret;
-+}
-+
-+static int rk818_usb_get_input_voltage_min(struct rk818_charger *cg,
-+ int *val)
-+{
-+ unsigned reg;
-+ int ret;
-+
-+ ret = regmap_read(cg->regmap, RK818_USB_CTRL_REG, ®);
-+ if (ret) {
-+ dev_err(cg->dev,
-+ "USB input voltage limit getting failed (%d)\n", ret);
-+ return ret;
-+ }
-+
-+ reg &= RK818_USB_CTRL_USB_CHG_SD_VSEL_MASK;
-+ reg >>= RK818_USB_CTRL_USB_CHG_SD_VSEL_OFFSET;
-+
-+ *val = 2780000 + (reg * 70000);
-+
-+ return 0;
-+}
-+
-+static int rk818_usb_power_get_property(struct power_supply *psy,
-+ enum power_supply_property psp,
-+ union power_supply_propval *val)
-+{
-+ struct rk818_charger *cg = power_supply_get_drvdata(psy);
-+ unsigned reg;
-+ int ret;
-+
-+ switch (psp) {
-+ case POWER_SUPPLY_PROP_PRESENT:
-+ ret = regmap_read(cg->regmap, RK818_SUP_STS_REG, ®);
-+ if (ret)
-+ return ret;
-+
-+ val->intval = !!(reg & RK818_SUP_STS_USB_EXS);
-+ break;
-+
-+ case POWER_SUPPLY_PROP_HEALTH:
-+ ret = regmap_read(cg->regmap, RK818_SUP_STS_REG, ®);
-+ if (ret)
-+ return ret;
-+
-+ if (!(reg & RK818_SUP_STS_USB_EXS)) {
-+ val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
-+ } else if (reg & RK818_SUP_STS_USB_EFF) {
-+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
-+ } else {
-+ val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
-+ }
-+
-+ break;
-+
-+ case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
-+ return rk818_usb_get_input_voltage_min(cg, &val->intval);
-+
-+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
-+ return rk818_usb_get_input_current_max(cg, &val->intval);
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int rk818_usb_power_set_property(struct power_supply *psy,
-+ enum power_supply_property psp,
-+ const union power_supply_propval *val)
-+{
-+ struct rk818_charger *cg = power_supply_get_drvdata(psy);
-+
-+ switch (psp) {
-+ case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
-+ return rk818_usb_set_input_voltage_min(cg, val->intval);
-+
-+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
-+ return rk818_usb_set_input_current_max(cg, val->intval);
-+
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static int rk818_usb_power_prop_writeable(struct power_supply *psy,
-+ enum power_supply_property psp)
-+{
-+ switch (psp) {
-+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
-+ case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
-+ return 1;
-+
-+ default:
-+ return 0;
-+ }
-+}
-+
-+/* Sync the input-current-limit with our parent supply (if we have one) */
-+static void rk818_usb_power_external_power_changed(struct power_supply *psy)
-+{
-+ struct rk818_charger *cg = power_supply_get_drvdata(psy);
-+
-+ power_supply_set_input_current_limit_from_supplier(cg->usb_psy);
-+}
-+
-+static enum power_supply_property rk818_usb_power_props[] = {
-+ POWER_SUPPLY_PROP_PRESENT,
-+ POWER_SUPPLY_PROP_HEALTH,
-+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
-+ POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT,
-+};
-+
-+static const struct power_supply_desc rk818_usb_desc = {
-+ .name = "rk818-usb",
-+ .type = POWER_SUPPLY_TYPE_USB,
-+ .properties = rk818_usb_power_props,
-+ .num_properties = ARRAY_SIZE(rk818_usb_power_props),
-+ .property_is_writeable = rk818_usb_power_prop_writeable,
-+ .get_property = rk818_usb_power_get_property,
-+ .set_property = rk818_usb_power_set_property,
-+ .external_power_changed = rk818_usb_power_external_power_changed,
-+};
-+
-+// }}}
-+// {{{ Charger supply
-+
-+static int rk818_charger_set_current_max(struct rk818_charger *cg, int val)
-+{
-+ unsigned reg;
-+ int ret;
-+
-+ if (val < 1000000)
-+ reg = 0;
-+ else if (val < 3000000)
-+ reg = (val - 1000000) / 200000;
-+ else
-+ reg = 10;
-+
-+ ret = regmap_update_bits(cg->regmap, RK818_CHRG_CTRL_REG1,
-+ RK818_CHRG_CTRL_REG1_CHRG_CUR_SEL_MASK,
-+ reg << RK818_CHRG_CTRL_REG1_CHRG_CUR_SEL_OFFSET);
-+ if (ret)
-+ dev_err(cg->dev,
-+ "Charging max current setting failed (%d)\n", ret);
-+
-+ return ret;
-+}
-+
-+static int rk818_charger_get_current_max(struct rk818_charger *cg, int *val)
-+{
-+ unsigned reg;
-+ int ret;
-+
-+ ret = regmap_read(cg->regmap, RK818_CHRG_CTRL_REG1, ®);
-+ if (ret) {
-+ dev_err(cg->dev,
-+ "Charging max current getting failed (%d)\n", ret);
-+ return ret;
-+ }
-+
-+ reg &= RK818_CHRG_CTRL_REG1_CHRG_CUR_SEL_MASK;
-+ reg >>= RK818_CHRG_CTRL_REG1_CHRG_CUR_SEL_OFFSET;
-+
-+ *val = 1000000 + reg * 200000;
-+
-+ return 0;
-+}
-+
-+static int rk818_charger_set_voltage_max(struct rk818_charger *cg, int val)
-+{
-+ unsigned reg;
-+ int ret;
-+
-+ if (val < 4050000)
-+ reg = 0;
-+ else if (val < 4350000)
-+ reg = (val - 4050000) / 50000;
-+ else
-+ reg = 6;
-+
-+ ret = regmap_update_bits(cg->regmap, RK818_CHRG_CTRL_REG1,
-+ RK818_CHRG_CTRL_REG1_CHRG_VOL_SEL_MASK,
-+ reg << RK818_CHRG_CTRL_REG1_CHRG_VOL_SEL_OFFSET);
-+ if (ret)
-+ dev_err(cg->dev,
-+ "Charging end voltage setting failed (%d)\n", ret);
-+
-+ return ret;
-+}
-+
-+static int rk818_charger_get_voltage_max(struct rk818_charger *cg, int *val)
-+{
-+ unsigned reg;
-+ int ret;
-+
-+ ret = regmap_read(cg->regmap, RK818_CHRG_CTRL_REG1, ®);
-+ if (ret) {
-+ dev_err(cg->dev,
-+ "Charging end voltage getting failed (%d)\n", ret);
-+ return ret;
-+ }
-+
-+ reg &= RK818_CHRG_CTRL_REG1_CHRG_VOL_SEL_MASK;
-+ reg >>= RK818_CHRG_CTRL_REG1_CHRG_VOL_SEL_OFFSET;
-+
-+ *val = 4050000 + reg * 50000;
-+
-+ return 0;
-+}
-+
-+static int rk818_charger_get_property(struct power_supply *psy,
-+ enum power_supply_property psp,
-+ union power_supply_propval *val)
-+{
-+ struct rk818_charger *cg = power_supply_get_drvdata(psy);
-+ unsigned reg;
-+ int ret;
-+
-+ switch (psp) {
-+ case POWER_SUPPLY_PROP_ONLINE:
-+ ret = regmap_read(cg->regmap, RK818_CHRG_CTRL_REG1, ®);
-+ if (ret) {
-+ dev_err(cg->dev, "failed to read the charger state (%d)\n", ret);
-+ return ret;
-+ }
-+
-+ val->intval = !!(reg & RK818_CHRG_CTRL_REG1_CHRG_EN);
-+ break;
-+
-+ case POWER_SUPPLY_PROP_STATUS:
-+ ret = regmap_read(cg->regmap, RK818_SUP_STS_REG, ®);
-+ if (ret)
-+ return ret;
-+
-+ switch (reg & RK818_CHG_STS_MASK) {
-+ case RK818_CHG_STS_WAKEUP_CUR:
-+ case RK818_CHG_STS_TRICKLE_CUR:
-+ case RK818_CHG_STS_CC_OR_CV:
-+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
-+ break;
-+ case RK818_CHG_STS_TERMINATED:
-+ default:
-+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
-+ break;
-+ }
-+
-+ break;
-+
-+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
-+ ret = regmap_read(cg->regmap, RK818_SUP_STS_REG, ®);
-+ if (ret)
-+ return ret;
-+
-+ switch (reg & RK818_CHG_STS_MASK) {
-+ case RK818_CHG_STS_WAKEUP_CUR:
-+ case RK818_CHG_STS_TRICKLE_CUR:
-+ val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
-+ break;
-+ case RK818_CHG_STS_CC_OR_CV:
-+ val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
-+ break;
-+ case RK818_CHG_STS_TERMINATED:
-+ val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
-+ break;
-+ default:
-+ val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
-+ break;
-+ }
-+
-+ break;
-+
-+ case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
-+ ret = regmap_read(cg->regmap, RK818_CHRG_CTRL_REG2, ®);
-+ if (ret)
-+ return ret;
-+
-+ val->intval = 100000 + ((reg >> 6) & 3) * 50000;
-+ break;
-+
-+ case POWER_SUPPLY_PROP_HEALTH:
-+ ret = regmap_read(cg->regmap, RK818_SUP_STS_REG, ®);
-+ if (ret)
-+ return ret;
-+
-+ switch (reg & RK818_CHG_STS_MASK) {
-+ case RK818_CHG_STS_USB_OV:
-+ val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
-+ break;
-+ case RK818_CHG_STS_BAT_TEMP_FAULT:
-+ val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
-+ break;
-+ case RK818_CHG_STS_TIMEOUT:
-+ val->intval = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
-+ break;
-+ default:
-+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
-+ break;
-+ }
-+
-+ break;
-+
-+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
-+ return rk818_charger_get_voltage_max(cg, &val->intval);
-+
-+ case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
-+ ret = rk818_charger_get_current_max(cg, &val->intval);
-+ val->intval /= 10;
-+ return ret;
-+
-+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
-+ return rk818_charger_get_current_max(cg, &val->intval);
-+
-+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
-+ val->intval = 4350000;
-+ break;
-+
-+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
-+ val->intval = 3000000;
-+ break;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int rk818_charger_set_property(struct power_supply *psy,
-+ enum power_supply_property psp,
-+ const union power_supply_propval *val)
-+{
-+ struct rk818_charger *cg = power_supply_get_drvdata(psy);
-+ int ret;
-+
-+ switch (psp) {
-+ case POWER_SUPPLY_PROP_ONLINE:
-+ ret = regmap_update_bits(cg->regmap, RK818_CHRG_CTRL_REG1,
-+ RK818_CHRG_CTRL_REG1_CHRG_EN,
-+ val->intval ? RK818_CHRG_CTRL_REG1_CHRG_EN : 0);
-+ if (ret)
-+ dev_err(cg->dev, "failed to setup the charger (%d)\n", ret);
-+
-+ return ret;
-+
-+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
-+ return rk818_charger_set_voltage_max(cg, val->intval);
-+
-+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
-+ return rk818_charger_set_current_max(cg, val->intval);
-+
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static int rk818_charger_prop_writeable(struct power_supply *psy,
-+ enum power_supply_property psp)
-+{
-+ switch (psp) {
-+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
-+ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
-+ case POWER_SUPPLY_PROP_ONLINE:
-+ return 1;
-+
-+ default:
-+ return 0;
-+ }
-+}
-+
-+static enum power_supply_property rk818_charger_props[] = {
-+ POWER_SUPPLY_PROP_ONLINE,
-+ POWER_SUPPLY_PROP_HEALTH,
-+ POWER_SUPPLY_PROP_STATUS,
-+ POWER_SUPPLY_PROP_CHARGE_TYPE,
-+ POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
-+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
-+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
-+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
-+ POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
-+ POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
-+};
-+
-+/*
-+ * TODO: This functionality should be in a battery driver/supply, but that one
-+ * is such a mess, I don't want to touch it now. Let's have a separate supply
-+ * for controlling the charger for now, and a prayer for the poor soul that
-+ * will have to understand and clean up the battery driver.
-+ */
-+static const struct power_supply_desc rk818_charger_desc = {
-+ .name = "rk818-charger",
-+ .type = POWER_SUPPLY_TYPE_MAINS,
-+ .properties = rk818_charger_props,
-+ .num_properties = ARRAY_SIZE(rk818_charger_props),
-+ .property_is_writeable = rk818_charger_prop_writeable,
-+ .get_property = rk818_charger_get_property,
-+ .set_property = rk818_charger_set_property,
-+};
-+
-+// }}}
-+
-+static int rk818_charger_probe(struct platform_device *pdev)
-+{
-+ struct rk808 *rk818 = dev_get_drvdata(pdev->dev.parent);
-+ struct power_supply_config psy_cfg = { };
-+ struct device *dev = &pdev->dev;
-+ struct rk818_charger *cg;
-+ int ret;
-+
-+ cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL);
-+ if (!cg)
-+ return -ENOMEM;
-+
-+ cg->rk818 = rk818;
-+ cg->dev = dev;
-+ cg->regmap = rk818->regmap;
-+ platform_set_drvdata(pdev, cg);
-+
-+ psy_cfg.drv_data = cg;
-+ psy_cfg.of_node = dev->of_node;
-+
-+ cg->usb_psy = devm_power_supply_register(dev, &rk818_usb_desc,
-+ &psy_cfg);
-+ if (IS_ERR(cg->usb_psy))
-+ return dev_err_probe(dev, PTR_ERR(cg->usb_psy),
-+ "register usb power supply fail\n");
-+
-+ cg->charger_psy = devm_power_supply_register(dev, &rk818_charger_desc,
-+ &psy_cfg);
-+ if (IS_ERR(cg->charger_psy))
-+ return dev_err_probe(dev, PTR_ERR(cg->charger_psy),
-+ "register charger power supply fail\n");
-+
-+ /* disable voltage limit and enable input current limit */
-+ ret = regmap_update_bits(cg->regmap, RK818_SUP_STS_REG,
-+ RK818_SUP_STS_USB_ILIM_EN | RK818_SUP_STS_USB_VLIM_EN,
-+ RK818_SUP_STS_USB_ILIM_EN);
-+ if (ret)
-+ dev_warn(cg->dev, "failed to enable input current limit (%d)\n", ret);
-+
-+ /* make sure analog control loop is enabled */
-+ ret = regmap_update_bits(cg->regmap, RK818_CHRG_CTRL_REG3,
-+ RK818_CHRG_CTRL_REG3_CHRG_TERM_DIGITAL,
-+ 0);
-+ if (ret)
-+ dev_warn(cg->dev, "failed to enable analog control loop (%d)\n", ret);
-+
-+ /* enable charger and set some reasonable limits on each boot */
-+ ret = regmap_write(cg->regmap, RK818_CHRG_CTRL_REG1,
-+ RK818_CHRG_CTRL_REG1_CHRG_EN
-+ | (1) /* 1.2A */
-+ | (5 << 4) /* 4.3V */);
-+ if (ret)
-+ dev_warn(cg->dev, "failed to enable charger (%d)\n", ret);
-+
-+ power_supply_set_input_current_limit_from_supplier(cg->usb_psy);
-+
-+ return 0;
-+}
-+
-+static int rk818_charger_remove(struct platform_device *pdev)
-+{
-+ //struct rk818_charger *cg = platform_get_drvdata(pdev);
-+
-+ return 0;
-+}
-+
-+static void rk818_charger_shutdown(struct platform_device *pdev)
-+{
-+}
-+
-+static int rk818_charger_suspend(struct platform_device *pdev,
-+ pm_message_t state)
-+{
-+ return 0;
-+}
-+
-+static int rk818_charger_resume(struct platform_device *pdev)
-+{
-+ return 0;
-+}
-+
-+static const struct of_device_id rk818_charger_of_match[] = {
-+ { .compatible = "rockchip,rk818-charger", },
-+ { },
-+};
-+
-+static struct platform_driver rk818_charger_driver = {
-+ .probe = rk818_charger_probe,
-+ .remove = rk818_charger_remove,
-+ .suspend = rk818_charger_suspend,
-+ .resume = rk818_charger_resume,
-+ .shutdown = rk818_charger_shutdown,
-+ .driver = {
-+ .name = "rk818-charger",
-+ .of_match_table = rk818_charger_of_match,
-+ },
-+};
-+
-+module_platform_driver(rk818_charger_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:rk818-charger");
-+MODULE_AUTHOR("Ondřej Jirman ");
diff --git a/sys-kernel/pinephone-pro-sources/files/0015-usb-typec-fusb302-Set-the-current-before-enabling-pu.patch b/sys-kernel/pinephone-pro-sources/files/0015-usb-typec-fusb302-Set-the-current-before-enabling-pu.patch
deleted file mode 100644
index f42aed2..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0015-usb-typec-fusb302-Set-the-current-before-enabling-pu.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 7 Nov 2021 19:28:27 +0100
-Subject: [PATCH 26/36] usb: typec: fusb302: Set the current before enabling
- pullups
-
-This seems more reasonable and should avoid short period of incorrect
-current setting being applied to CC pin.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/usb/typec/tcpm/fusb302.c | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
-index 72f9001..776a949 100644
---- a/drivers/usb/typec/tcpm/fusb302.c
-+++ b/drivers/usb/typec/tcpm/fusb302.c
-@@ -635,6 +635,14 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
- goto done;
- }
-
-+ /* adjust current for SRC */
-+ ret = fusb302_set_src_current(chip, cc_src_current[cc]);
-+ if (ret < 0) {
-+ fusb302_log(chip, "cannot set src current %s, ret=%d",
-+ typec_cc_status_name[cc], ret);
-+ goto done;
-+ }
-+
- ret = fusb302_i2c_mask_write(chip, FUSB_REG_SWITCHES0,
- switches0_mask, switches0_data);
- if (ret < 0) {
-@@ -645,14 +653,6 @@ static int tcpm_set_cc(struct tcpc_dev *dev, enum typec_cc_status cc)
- chip->cc1 = TYPEC_CC_OPEN;
- chip->cc2 = TYPEC_CC_OPEN;
-
-- /* adjust current for SRC */
-- ret = fusb302_set_src_current(chip, cc_src_current[cc]);
-- if (ret < 0) {
-- fusb302_log(chip, "cannot set src current %s, ret=%d",
-- typec_cc_status_name[cc], ret);
-- goto done;
-- }
--
- /* enable/disable interrupts, BC_LVL for SNK and COMP_CHNG for SRC */
- switch (cc) {
- case TYPEC_CC_RP_DEF:
diff --git a/sys-kernel/pinephone-pro-sources/files/0016-usb-typec-fusb302-Extend-debugging-interface-with-dr.patch b/sys-kernel/pinephone-pro-sources/files/0016-usb-typec-fusb302-Extend-debugging-interface-with-dr.patch
deleted file mode 100644
index 0ab3229..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0016-usb-typec-fusb302-Extend-debugging-interface-with-dr.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 7 Nov 2021 19:29:06 +0100
-Subject: [PATCH 27/36] usb: typec: fusb302: Extend debugging interface with
- driver state dumps
-
-This is useful for debugging.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/usb/typec/tcpm/fusb302.c | 78 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 78 insertions(+)
-
-diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
-index 776a949..1a758e3 100644
---- a/drivers/usb/typec/tcpm/fusb302.c
-+++ b/drivers/usb/typec/tcpm/fusb302.c
-@@ -207,6 +207,81 @@ static int fusb302_debug_show(struct seq_file *s, void *v)
- }
- DEFINE_SHOW_ATTRIBUTE(fusb302_debug);
-
-+static const char * const typec_cc_status_name[];
-+static const char * const cc_polarity_name[];
-+static const char * const toggling_mode_name[] = {
-+ [TOGGLING_MODE_OFF] = "Off",
-+ [TOGGLING_MODE_DRP] = "DRP",
-+ [TOGGLING_MODE_SNK] = "SNK",
-+ [TOGGLING_MODE_SRC] = "SRC",
-+};
-+static const char * const src_current_status_name[] = {
-+ [SRC_CURRENT_DEFAULT] = "Default",
-+ [SRC_CURRENT_MEDIUM] = "Medium",
-+ [SRC_CURRENT_HIGH] = "High",
-+};
-+
-+#define FUSB_REG(n) { n, #n },
-+struct fusb_reg {
-+ u8 addr;
-+ const char* name;
-+} fusb_regs[] = {
-+ FUSB_REG(FUSB_REG_DEVICE_ID)
-+ FUSB_REG(FUSB_REG_SWITCHES0)
-+ FUSB_REG(FUSB_REG_SWITCHES1)
-+ FUSB_REG(FUSB_REG_MEASURE)
-+ FUSB_REG(FUSB_REG_CONTROL0)
-+ FUSB_REG(FUSB_REG_CONTROL1)
-+ FUSB_REG(FUSB_REG_CONTROL2)
-+ FUSB_REG(FUSB_REG_CONTROL3)
-+ FUSB_REG(FUSB_REG_MASK)
-+ FUSB_REG(FUSB_REG_POWER)
-+ FUSB_REG(FUSB_REG_RESET)
-+ FUSB_REG(FUSB_REG_MASKA)
-+ FUSB_REG(FUSB_REG_MASKB)
-+ FUSB_REG(FUSB_REG_STATUS0A)
-+ FUSB_REG(FUSB_REG_STATUS1A)
-+ FUSB_REG(FUSB_REG_INTERRUPTA)
-+ FUSB_REG(FUSB_REG_INTERRUPTB)
-+ FUSB_REG(FUSB_REG_STATUS0)
-+ FUSB_REG(FUSB_REG_STATUS1)
-+ FUSB_REG(FUSB_REG_INTERRUPT)
-+};
-+
-+static int fusb302_i2c_read(struct fusb302_chip *chip,
-+ u8 address, u8 *data);
-+
-+static int fusb302_debug_regs_show(struct seq_file *s, void *v)
-+{
-+ struct fusb302_chip *chip = (struct fusb302_chip *)s->private;
-+ int i, ret;
-+
-+ seq_printf(s, "chip->intr_togdone = %d\n", chip->intr_togdone);
-+ seq_printf(s, "chip->intr_bc_lvl = %d\n", chip->intr_bc_lvl);
-+ seq_printf(s, "chip->intr_comp_chng = %d\n", chip->intr_comp_chng);
-+ seq_printf(s, "chip->vconn_on = %d\n", chip->vconn_on);
-+ seq_printf(s, "chip->vbus_on = %d\n", chip->vbus_on);
-+ seq_printf(s, "chip->charge_on = %d\n", chip->charge_on);
-+ seq_printf(s, "chip->vbus_present = %d\n", chip->vbus_present);
-+ seq_printf(s, "chip->cc_polarity = %s\n", cc_polarity_name[chip->cc_polarity]);
-+ seq_printf(s, "chip->cc1 = %s\n", typec_cc_status_name[chip->cc1]);
-+ seq_printf(s, "chip->cc2 = %s\n", typec_cc_status_name[chip->cc2]);
-+ seq_printf(s, "chip->toggling_mode = %s\n", toggling_mode_name[chip->toggling_mode]);
-+ seq_printf(s, "chip->src_current_status = %s\n", src_current_status_name[chip->src_current_status]);
-+
-+ seq_printf(s, "\nRegisters:\n");
-+ for (i = 0; i < ARRAY_SIZE(fusb_regs); i++) {
-+ u8 val = 0;
-+
-+ ret = fusb302_i2c_read(chip, fusb_regs[i].addr, &val);
-+ if (ret >= 0)
-+ seq_printf(s, "%s = %02hhx\n", fusb_regs[i].name, val);
-+ }
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(fusb302_debug_regs);
-+
- static void fusb302_debugfs_init(struct fusb302_chip *chip)
- {
- char name[NAME_MAX];
-@@ -216,6 +291,9 @@ static void fusb302_debugfs_init(struct fusb302_chip *chip)
- chip->dentry = debugfs_create_dir(name, usb_debug_root);
- debugfs_create_file("log", S_IFREG | 0444, chip->dentry, chip,
- &fusb302_debug_fops);
-+
-+ debugfs_create_file("regs", S_IFREG | 0444, chip->dentry, chip,
-+ &fusb302_debug_regs_fops);
- }
-
- static void fusb302_debugfs_exit(struct fusb302_chip *chip)
diff --git a/sys-kernel/pinephone-pro-sources/files/0017-usb-typec-fusb302-Retry-reading-of-CC-pins-status-if.patch b/sys-kernel/pinephone-pro-sources/files/0017-usb-typec-fusb302-Retry-reading-of-CC-pins-status-if.patch
deleted file mode 100644
index 096673e..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0017-usb-typec-fusb302-Retry-reading-of-CC-pins-status-if.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From: Ondrej Jirman
-Date: Tue, 23 Nov 2021 17:53:27 +0100
-Subject: [PATCH 28/36] usb: typec: fusb302: Retry reading of CC pins status
- if activity is detected
-
-This is just for testing, to see if this ever happens. It should
-also help when this happens.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/usb/typec/tcpm/fusb302.c | 34 ++++++++++++++++++++++++++++++++--
- 1 file changed, 32 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
-index 1a758e3..7386805 100644
---- a/drivers/usb/typec/tcpm/fusb302.c
-+++ b/drivers/usb/typec/tcpm/fusb302.c
-@@ -1317,6 +1317,36 @@ static int fusb302_handle_togdone_snk(struct fusb302_chip *chip,
- return ret;
- }
-
-+static int fusb302_get_status0_stable(struct fusb302_chip *chip, u8 *status0)
-+{
-+ int ret, tries = 0;
-+ u8 reg;
-+
-+try_again:
-+ ret = fusb302_i2c_read(chip, FUSB_REG_STATUS0, ®);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (reg & FUSB_REG_STATUS0_ACTIVITY) {
-+ fusb302_log(chip, "activity reading CC status");
-+ if (++tries == 5) {
-+ fusb302_log(chip, "failed to read stable status0 value");
-+
-+ /*
-+ * The best we can do is to return at least something.
-+ */
-+ *status0 = reg;
-+ return 0;
-+ }
-+
-+ usleep_range(50, 100);
-+ goto try_again;
-+ }
-+
-+ *status0 = reg;
-+ return 0;
-+}
-+
- /* On error returns < 0, otherwise a typec_cc_status value */
- static int fusb302_get_src_cc_status(struct fusb302_chip *chip,
- enum typec_cc_polarity cc_polarity,
-@@ -1344,7 +1374,7 @@ static int fusb302_get_src_cc_status(struct fusb302_chip *chip,
- return ret;
-
- usleep_range(50, 100);
-- ret = fusb302_i2c_read(chip, FUSB_REG_STATUS0, &status0);
-+ ret = fusb302_get_status0_stable(chip, &status0);
- if (ret < 0)
- return ret;
-
-@@ -1360,7 +1390,7 @@ static int fusb302_get_src_cc_status(struct fusb302_chip *chip,
- return ret;
-
- usleep_range(50, 100);
-- ret = fusb302_i2c_read(chip, FUSB_REG_STATUS0, &status0);
-+ ret = fusb302_get_status0_stable(chip, &status0);
- if (ret < 0)
- return ret;
-
diff --git a/sys-kernel/pinephone-pro-sources/files/0018-usb-typec-fusb302-More-useful-of-logging-status-on-i.patch b/sys-kernel/pinephone-pro-sources/files/0018-usb-typec-fusb302-More-useful-of-logging-status-on-i.patch
deleted file mode 100644
index 2cec92e..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0018-usb-typec-fusb302-More-useful-of-logging-status-on-i.patch
+++ /dev/null
@@ -1,186 +0,0 @@
-From: Ondrej Jirman
-Date: Tue, 23 Nov 2021 17:55:34 +0100
-Subject: [PATCH 29/36] usb: typec: fusb302: More useful of logging status on
- interrupt
-
-This is just for debugging. It prints more info that's useful to
-see how hardware state changes in time.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/usb/typec/tcpm/fusb302.c | 121 +++++++++++++++++++++++++++++++++------
- 1 file changed, 104 insertions(+), 17 deletions(-)
-
-diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
-index 7386805..70b0e15 100644
---- a/drivers/usb/typec/tcpm/fusb302.c
-+++ b/drivers/usb/typec/tcpm/fusb302.c
-@@ -68,7 +68,7 @@ static const u8 rd_mda_value[] = {
- };
-
- #define LOG_BUFFER_ENTRIES 1024
--#define LOG_BUFFER_ENTRY_SIZE 128
-+#define LOG_BUFFER_ENTRY_SIZE 256
-
- struct fusb302_chip {
- struct device *dev;
-@@ -1598,6 +1598,84 @@ static irqreturn_t fusb302_irq_intn(int irq, void *dev_id)
- return IRQ_HANDLED;
- }
-
-+static void fusb302_print_state(struct fusb302_chip *chip)
-+{
-+ u8 ctl0, ctl2, measure, status0, status1a, sw0, mask;
-+ int ret;
-+
-+ ret = fusb302_i2c_read(chip, FUSB_REG_CONTROL0, &ctl0);
-+ if (ret < 0)
-+ return;
-+ ret = fusb302_i2c_read(chip, FUSB_REG_CONTROL2, &ctl2);
-+ if (ret < 0)
-+ return;
-+ ret = fusb302_i2c_read(chip, FUSB_REG_MEASURE, &measure);
-+ if (ret < 0)
-+ return;
-+ ret = fusb302_i2c_read(chip, FUSB_REG_STATUS0, &status0);
-+ if (ret < 0)
-+ return;
-+ ret = fusb302_i2c_read(chip, FUSB_REG_STATUS1A, &status1a);
-+ if (ret < 0)
-+ return;
-+ ret = fusb302_i2c_read(chip, FUSB_REG_SWITCHES0, &sw0);
-+ if (ret < 0)
-+ return;
-+ ret = fusb302_i2c_read(chip, FUSB_REG_MASK, &mask);
-+ if (ret < 0)
-+ return;
-+
-+ //FUSB_REG(FUSB_REG_POWER) // power control
-+
-+ const char* host_cur = "?";
-+ switch ((ctl0 >> 2) & 3) {
-+ case 0: host_cur = "none"; break;
-+ case 1: host_cur = "80uA"; break;
-+ case 2: host_cur = "160uA"; break;
-+ case 3: host_cur = "330uA"; break;
-+ }
-+
-+ const char* bc_lvl = "?";
-+ switch (status0 & 3) {
-+ case 0: bc_lvl = "0-200mV"; break;
-+ case 1: bc_lvl = "200-660mV"; break;
-+ case 2: bc_lvl = "660-1230mV"; break;
-+ case 3: bc_lvl = ">1230mV"; break;
-+ }
-+
-+ // status0
-+ unsigned vbusok = !!(status0 & BIT(7));
-+ unsigned activity = !!(status0 & BIT(6));
-+ unsigned comp = !!(status0 & BIT(5));
-+ unsigned wake = !!(status0 & BIT(2));
-+
-+ // measure
-+ unsigned mdac = ((measure & 0x3f) + 1) * 42 * (measure & BIT(6) ? 10 : 1);
-+
-+ // status1a
-+ unsigned togss = (status1a >> 3) & 7;
-+ const char* togss_s = "?";
-+ switch (togss) {
-+ case 0: togss_s = "running"; break;
-+ case 1: togss_s = "src1"; break;
-+ case 2: togss_s = "src2"; break;
-+ case 5: togss_s = "snk1"; break;
-+ case 6: togss_s = "snk2"; break;
-+ case 7: togss_s = "audio"; break;
-+ }
-+
-+ // ctl2 print as is
-+
-+#define SW(n) (!!(sw0 & BIT(n)))
-+
-+ fusb302_log(chip, "state: cc(puen=%u%u vconn=%u%u meas=%u%u pdwn=%u%u) "
-+ "host_cur=%s mdac=%umV comp=%u bc_lvl=%s vbusok=%u act=%u "
-+ "wake=%u togss=%s ctl2=0x%02x mask=0x%02x",
-+ SW(6), SW(7), SW(4), SW(5), SW(2), SW(3), SW(0), SW(1),
-+ host_cur, mdac, comp, bc_lvl, vbusok, activity,
-+ wake, togss_s, ctl2, mask);
-+}
-+
- static void fusb302_irq_work(struct work_struct *work)
- {
- struct fusb302_chip *chip = container_of(work, struct fusb302_chip,
-@@ -1607,6 +1685,7 @@ static void fusb302_irq_work(struct work_struct *work)
- u8 interrupta;
- u8 interruptb;
- u8 status0;
-+ u8 mda;
- bool vbus_present;
- bool comp_result;
- bool intr_togdone;
-@@ -1632,9 +1711,10 @@ static void fusb302_irq_work(struct work_struct *work)
- ret = fusb302_i2c_read(chip, FUSB_REG_STATUS0, &status0);
- if (ret < 0)
- goto done;
-- fusb302_log(chip,
-- "IRQ: 0x%02x, a: 0x%02x, b: 0x%02x, status0: 0x%02x",
-- interrupt, interrupta, interruptb, status0);
-+ fusb302_log(chip, "IRQ: 0x%02x, a: 0x%02x, b: 0x%02x",
-+ interrupt, interrupta, interruptb);
-+
-+ fusb302_print_state(chip);
-
- if (interrupt & FUSB_REG_INTERRUPT_VBUSOK) {
- vbus_present = !!(status0 & FUSB_REG_STATUS0_VBUSOK);
-@@ -1646,32 +1726,39 @@ static void fusb302_irq_work(struct work_struct *work)
- }
- }
-
-- if ((interrupta & FUSB_REG_INTERRUPTA_TOGDONE) && intr_togdone) {
-+ if (interrupta & FUSB_REG_INTERRUPTA_TOGDONE) {
- fusb302_log(chip, "IRQ: TOGDONE");
-- ret = fusb302_handle_togdone(chip);
-- if (ret < 0) {
-- fusb302_log(chip,
-- "handle togdone error, ret=%d", ret);
-- goto done;
-+ if (intr_togdone) {
-+ ret = fusb302_handle_togdone(chip);
-+ if (ret < 0) {
-+ fusb302_log(chip,
-+ "handle togdone error, ret=%d", ret);
-+ goto done;
-+ }
- }
- }
-
-- if ((interrupt & FUSB_REG_INTERRUPT_BC_LVL) && intr_bc_lvl) {
-+ if (interrupt & FUSB_REG_INTERRUPT_BC_LVL) {
- fusb302_log(chip, "IRQ: BC_LVL, handler pending");
- /*
- * as BC_LVL interrupt can be affected by PD activity,
- * apply delay to for the handler to wait for the PD
- * signaling to finish.
- */
-- mod_delayed_work(chip->wq, &chip->bc_lvl_handler,
-- msecs_to_jiffies(T_BC_LVL_DEBOUNCE_DELAY_MS));
-+ if (intr_bc_lvl)
-+ mod_delayed_work(chip->wq, &chip->bc_lvl_handler,
-+ msecs_to_jiffies(T_BC_LVL_DEBOUNCE_DELAY_MS));
- }
-
-- if ((interrupt & FUSB_REG_INTERRUPT_COMP_CHNG) && intr_comp_chng) {
-+ if (interrupt & FUSB_REG_INTERRUPT_COMP_CHNG) {
-+ ret = fusb302_i2c_read(chip, FUSB_REG_MEASURE, &mda);
-+ if (ret < 0)
-+ goto done;
-+
- comp_result = !!(status0 & FUSB_REG_STATUS0_COMP);
-- fusb302_log(chip, "IRQ: COMP_CHNG, comp=%s",
-- comp_result ? "true" : "false");
-- if (comp_result) {
-+ fusb302_log(chip, "IRQ: COMP_CHNG, cc* %s mdac (%u mV)",
-+ comp_result ? ">" : "<", ((mda & 0x3f) + 1) * 42 * (mda & BIT(6) ? 10 : 1));
-+ if (comp_result && intr_comp_chng) {
- /* cc level > Rd_threshold, detach */
- chip->cc1 = TYPEC_CC_OPEN;
- chip->cc2 = TYPEC_CC_OPEN;
diff --git a/sys-kernel/pinephone-pro-sources/files/0019-usb-typec-fusb302-Update-VBUS-state-even-if-VBUS-int.patch b/sys-kernel/pinephone-pro-sources/files/0019-usb-typec-fusb302-Update-VBUS-state-even-if-VBUS-int.patch
deleted file mode 100644
index 9335999..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0019-usb-typec-fusb302-Update-VBUS-state-even-if-VBUS-int.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From: Ondrej Jirman
-Date: Tue, 23 Nov 2021 17:57:06 +0100
-Subject: [PATCH 30/36] usb: typec: fusb302: Update VBUS state even if VBUS
- interrupt is not triggered
-
-This seems to improve robustness.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/usb/typec/tcpm/fusb302.c | 14 ++++++++------
- 1 file changed, 8 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
-index 70b0e15..1d5affa 100644
---- a/drivers/usb/typec/tcpm/fusb302.c
-+++ b/drivers/usb/typec/tcpm/fusb302.c
-@@ -1716,14 +1716,16 @@ static void fusb302_irq_work(struct work_struct *work)
-
- fusb302_print_state(chip);
-
-- if (interrupt & FUSB_REG_INTERRUPT_VBUSOK) {
-- vbus_present = !!(status0 & FUSB_REG_STATUS0_VBUSOK);
-+ vbus_present = !!(status0 & FUSB_REG_STATUS0_VBUSOK);
-+ if (interrupt & FUSB_REG_INTERRUPT_VBUSOK)
- fusb302_log(chip, "IRQ: VBUS_OK, vbus=%s",
- vbus_present ? "On" : "Off");
-- if (vbus_present != chip->vbus_present) {
-- chip->vbus_present = vbus_present;
-- tcpm_vbus_change(chip->tcpm_port);
-- }
-+ if (vbus_present != chip->vbus_present) {
-+ chip->vbus_present = vbus_present;
-+ if (!(interrupt & FUSB_REG_INTERRUPT_VBUSOK))
-+ fusb302_log(chip, "IRQ: VBUS changed without interrupt, vbus=%s",
-+ vbus_present ? "On" : "Off");
-+ tcpm_vbus_change(chip->tcpm_port);
- }
-
- if (interrupta & FUSB_REG_INTERRUPTA_TOGDONE) {
diff --git a/sys-kernel/pinephone-pro-sources/files/0020-usb-typec-fusb302-Make-tcpm-fusb302-logs-less-pollut.patch b/sys-kernel/pinephone-pro-sources/files/0020-usb-typec-fusb302-Make-tcpm-fusb302-logs-less-pollut.patch
deleted file mode 100644
index 9a880fd..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0020-usb-typec-fusb302-Make-tcpm-fusb302-logs-less-pollut.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From: Ondrej Jirman
-Date: Tue, 23 Nov 2021 17:58:05 +0100
-Subject: [PATCH 31/36] usb: typec: fusb302: Make tcpm/fusb302 logs less
- polluted by PD comm stuff
-
-This adds clarity to debugging.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/usb/typec/tcpm/fusb302.c | 18 ++++++++++--------
- drivers/usb/typec/tcpm/tcpm.c | 18 ++++++++++--------
- 2 files changed, 20 insertions(+), 16 deletions(-)
-
-diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
-index 1d5affa..ae3b930 100644
---- a/drivers/usb/typec/tcpm/fusb302.c
-+++ b/drivers/usb/typec/tcpm/fusb302.c
-@@ -787,7 +787,7 @@ static int tcpm_get_cc(struct tcpc_dev *dev, enum typec_cc_status *cc1,
- mutex_lock(&chip->lock);
- *cc1 = chip->cc1;
- *cc2 = chip->cc2;
-- fusb302_log(chip, "cc1=%s, cc2=%s", typec_cc_status_name[*cc1],
-+ fusb302_log(chip, "tcpm_get_cc => cc1=%s, cc2=%s (cached)", typec_cc_status_name[*cc1],
- typec_cc_status_name[*cc2]);
- mutex_unlock(&chip->lock);
-
-@@ -1073,8 +1073,8 @@ static int fusb302_pd_send_message(struct fusb302_chip *chip,
- ret = fusb302_i2c_block_write(chip, FUSB_REG_FIFOS, pos, buf);
- if (ret < 0)
- return ret;
-- fusb302_log(chip, "sending PD message header: %x", msg->header);
-- fusb302_log(chip, "sending PD message len: %d", len);
-+ //fusb302_log(chip, "sending PD message header: %x", msg->header);
-+ //fusb302_log(chip, "sending PD message len: %d", len);
-
- return ret;
- }
-@@ -1365,8 +1365,10 @@ static int fusb302_get_src_cc_status(struct fusb302_chip *chip,
- if (ret < 0)
- return ret;
-
-+ //XXX resolve activity conflicts while measuring
-+
- fusb302_i2c_read(chip, FUSB_REG_SWITCHES0, &status0);
-- fusb302_log(chip, "get_src_cc_status switches: 0x%0x", status0);
-+ //fusb302_log(chip, "get_src_cc_status switches: 0x%0x", status0);
-
- /* Step 2: Set compararator volt to differentiate between Open and Rd */
- ret = fusb302_i2c_write(chip, FUSB_REG_MEASURE, rd_mda);
-@@ -1378,7 +1380,7 @@ static int fusb302_get_src_cc_status(struct fusb302_chip *chip,
- if (ret < 0)
- return ret;
-
-- fusb302_log(chip, "get_src_cc_status rd_mda status0: 0x%0x", status0);
-+ //fusb302_log(chip, "get_src_cc_status rd_mda status0: 0x%0x", status0);
- if (status0 & FUSB_REG_STATUS0_COMP) {
- *cc = TYPEC_CC_OPEN;
- return 0;
-@@ -1394,7 +1396,7 @@ static int fusb302_get_src_cc_status(struct fusb302_chip *chip,
- if (ret < 0)
- return ret;
-
-- fusb302_log(chip, "get_src_cc_status ra_mda status0: 0x%0x", status0);
-+ //fusb302_log(chip, "get_src_cc_status ra_mda status0: 0x%0x", status0);
- if (status0 & FUSB_REG_STATUS0_COMP)
- *cc = TYPEC_CC_RD;
- else
-@@ -1559,8 +1561,8 @@ static int fusb302_pd_read_message(struct fusb302_chip *chip,
- ret = fusb302_i2c_block_read(chip, FUSB_REG_FIFOS, 4, crc);
- if (ret < 0)
- return ret;
-- fusb302_log(chip, "PD message header: %x", msg->header);
-- fusb302_log(chip, "PD message len: %d", len);
-+ //fusb302_log(chip, "PD message header: %x", msg->header);
-+ //fusb302_log(chip, "PD message len: %d", len);
-
- /*
- * Check if we've read off a GoodCRC message. If so then indicate to
-diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
-index 59d4fa2..0451441 100644
---- a/drivers/usb/typec/tcpm/tcpm.c
-+++ b/drivers/usb/typec/tcpm/tcpm.c
-@@ -776,7 +776,7 @@ static void tcpm_debugfs_exit(const struct tcpm_port *port) { }
-
- static void tcpm_set_cc(struct tcpm_port *port, enum typec_cc_status cc)
- {
-- tcpm_log(port, "cc:=%d", cc);
-+ //tcpm_log(port, "cc:=%d", cc);
- port->cc_req = cc;
- port->tcpc->set_cc(port->tcpc, cc);
- }
-@@ -869,10 +869,12 @@ static int tcpm_pd_transmit(struct tcpm_port *port,
- unsigned long timeout;
- int ret;
-
-+ /*
- if (msg)
- tcpm_log(port, "PD TX, header: %#x", le16_to_cpu(msg->header));
- else
- tcpm_log(port, "PD TX, type: %#x", type);
-+ */
-
- reinit_completion(&port->tx_complete);
- ret = port->tcpc->pd_transmit(port->tcpc, type, msg, port->negotiated_rev);
-@@ -918,7 +920,7 @@ static int tcpm_pd_transmit(struct tcpm_port *port,
- void tcpm_pd_transmit_complete(struct tcpm_port *port,
- enum tcpm_transmit_status status)
- {
-- tcpm_log(port, "PD TX complete, status: %u", status);
-+ //tcpm_log(port, "PD TX complete, status: %u", status);
- port->tx_status = status;
- complete(&port->tx_complete);
- }
-@@ -951,7 +953,7 @@ static int tcpm_set_polarity(struct tcpm_port *port,
- {
- int ret;
-
-- tcpm_log(port, "polarity %d", polarity);
-+ //tcpm_log(port, "polarity %d", polarity);
-
- ret = port->tcpc->set_polarity(port->tcpc, polarity);
- if (ret < 0)
-@@ -966,7 +968,7 @@ static int tcpm_set_vconn(struct tcpm_port *port, bool enable)
- {
- int ret;
-
-- tcpm_log(port, "vconn:=%d", enable);
-+ //tcpm_log(port, "vconn:=%d", enable);
-
- ret = port->tcpc->set_vconn(port->tcpc, enable);
- if (!ret) {
-@@ -2871,8 +2873,8 @@ static void tcpm_pd_rx_handler(struct kthread_work *work)
-
- mutex_lock(&port->lock);
-
-- tcpm_log(port, "PD RX, header: %#x [%d]", le16_to_cpu(msg->header),
-- port->attached);
-+ //tcpm_log(port, "PD RX, header: %#x [%d]", le16_to_cpu(msg->header),
-+ //port->attached);
-
- if (port->attached) {
- enum pd_ctrl_msg_type type = pd_header_type_le(msg->header);
-@@ -5041,7 +5043,7 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
-
- static void _tcpm_pd_vbus_on(struct tcpm_port *port)
- {
-- tcpm_log_force(port, "VBUS on");
-+ tcpm_log_force(port, "VBUS event received: on");
- port->vbus_present = true;
- /*
- * When vbus_present is true i.e. Voltage at VBUS is greater than VSAFE5V implicitly
-@@ -5131,7 +5133,7 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port)
-
- static void _tcpm_pd_vbus_off(struct tcpm_port *port)
- {
-- tcpm_log_force(port, "VBUS off");
-+ tcpm_log_force(port, "VBUS event received: off");
- port->vbus_present = false;
- port->vbus_never_low = false;
- switch (port->state) {
diff --git a/sys-kernel/pinephone-pro-sources/files/0021-usb-typec-fusb302-Add-OF-extcon-support.patch b/sys-kernel/pinephone-pro-sources/files/0021-usb-typec-fusb302-Add-OF-extcon-support.patch
deleted file mode 100644
index 64f2ffa..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0021-usb-typec-fusb302-Add-OF-extcon-support.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 14 Nov 2021 01:14:25 +0100
-Subject: [PATCH 32/36] usb: typec: fusb302: Add OF extcon support
-
-It's possible to create a dependency cycle between fusb302 and
-other drivers via extcon device, so we retrieve the device on
-demand after probe and not during probe.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/usb/typec/tcpm/fusb302.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
-index ae3b930..0c5dd00 100644
---- a/drivers/usb/typec/tcpm/fusb302.c
-+++ b/drivers/usb/typec/tcpm/fusb302.c
-@@ -518,6 +518,16 @@ static int tcpm_get_current_limit(struct tcpc_dev *dev)
- int current_limit = 0;
- unsigned long timeout;
-
-+ /*
-+ * To avoid cycles in OF dependencies, we get extcon when necessary
-+ * outside of probe function.
-+ */
-+ if (of_property_read_bool(chip->dev->of_node, "extcon") && !chip->extcon) {
-+ chip->extcon = extcon_get_edev_by_phandle(chip->dev, 0);
-+ if (IS_ERR(chip->extcon))
-+ chip->extcon = NULL;
-+ }
-+
- if (!chip->extcon)
- return 0;
-
diff --git a/sys-kernel/pinephone-pro-sources/files/0022-usb-typec-fusb302-Fix-register-definitions.patch b/sys-kernel/pinephone-pro-sources/files/0022-usb-typec-fusb302-Fix-register-definitions.patch
deleted file mode 100644
index f06e87f..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0022-usb-typec-fusb302-Fix-register-definitions.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From: Ondrej Jirman
-Date: Sat, 20 Nov 2021 14:33:58 +0100
-Subject: [PATCH 33/36] usb: typec: fusb302: Fix register definitions
-
-MEASURE_VBUS bit is at position 6. MDAC bits are also wrong.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/usb/typec/tcpm/fusb302_reg.h | 16 +++++++---------
- 1 file changed, 7 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/usb/typec/tcpm/fusb302_reg.h b/drivers/usb/typec/tcpm/fusb302_reg.h
-index edc0e4b..f37d226 100644
---- a/drivers/usb/typec/tcpm/fusb302_reg.h
-+++ b/drivers/usb/typec/tcpm/fusb302_reg.h
-@@ -27,14 +27,13 @@
- #define FUSB_REG_SWITCHES1_TXCC2_EN BIT(1)
- #define FUSB_REG_SWITCHES1_TXCC1_EN BIT(0)
- #define FUSB_REG_MEASURE 0x04
--#define FUSB_REG_MEASURE_MDAC5 BIT(7)
--#define FUSB_REG_MEASURE_MDAC4 BIT(6)
--#define FUSB_REG_MEASURE_MDAC3 BIT(5)
--#define FUSB_REG_MEASURE_MDAC2 BIT(4)
--#define FUSB_REG_MEASURE_MDAC1 BIT(3)
--#define FUSB_REG_MEASURE_MDAC0 BIT(2)
--#define FUSB_REG_MEASURE_VBUS BIT(1)
--#define FUSB_REG_MEASURE_XXXX5 BIT(0)
-+#define FUSB_REG_MEASURE_VBUS BIT(6)
-+#define FUSB_REG_MEASURE_MDAC5 BIT(5)
-+#define FUSB_REG_MEASURE_MDAC4 BIT(4)
-+#define FUSB_REG_MEASURE_MDAC3 BIT(3)
-+#define FUSB_REG_MEASURE_MDAC2 BIT(2)
-+#define FUSB_REG_MEASURE_MDAC1 BIT(1)
-+#define FUSB_REG_MEASURE_MDAC0 BIT(0)
- #define FUSB_REG_CONTROL0 0x06
- #define FUSB_REG_CONTROL0_TX_FLUSH BIT(6)
- #define FUSB_REG_CONTROL0_INT_MASK BIT(5)
-@@ -105,7 +104,6 @@
- #define FUSB_REG_STATUS0A_RX_SOFT_RESET BIT(1)
- #define FUSB_REG_STATUS0A_RX_HARD_RESET BIT(0)
- #define FUSB_REG_STATUS1A 0x3D
--#define FUSB_REG_STATUS1A_TOGSS BIT(3)
- #define FUSB_REG_STATUS1A_TOGSS_RUNNING 0x0
- #define FUSB_REG_STATUS1A_TOGSS_SRC1 0x1
- #define FUSB_REG_STATUS1A_TOGSS_SRC2 0x2
diff --git a/sys-kernel/pinephone-pro-sources/files/0023-usb-typec-fusb302-Clear-interrupts-before-we-start-t.patch b/sys-kernel/pinephone-pro-sources/files/0023-usb-typec-fusb302-Clear-interrupts-before-we-start-t.patch
deleted file mode 100644
index 5909161..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0023-usb-typec-fusb302-Clear-interrupts-before-we-start-t.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Ondrej Jirman
-Date: Sat, 20 Nov 2021 14:35:10 +0100
-Subject: [PATCH 34/36] usb: typec: fusb302: Clear interrupts before we start
- toggling
-
-This is recommended by the datasheet.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/usb/typec/tcpm/fusb302.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
-index 0c5dd00..011dce5 100644
---- a/drivers/usb/typec/tcpm/fusb302.c
-+++ b/drivers/usb/typec/tcpm/fusb302.c
-@@ -586,6 +586,7 @@ static int fusb302_set_toggling(struct fusb302_chip *chip,
- enum toggling_mode mode)
- {
- int ret = 0;
-+ u8 reg;
-
- /* first disable toggling */
- ret = fusb302_i2c_clear_bits(chip, FUSB_REG_CONTROL2,
-@@ -644,6 +645,12 @@ static int fusb302_set_toggling(struct fusb302_chip *chip,
- } else {
- /* Datasheet says vconn MUST be off when toggling */
- WARN(chip->vconn_on, "Vconn is on during toggle start");
-+
-+ /* clear interrupts */
-+ ret = fusb302_i2c_read(chip, FUSB_REG_INTERRUPT, ®);
-+ if (ret < 0)
-+ return ret;
-+
- /* unmask TOGDONE interrupt */
- ret = fusb302_i2c_clear_bits(chip, FUSB_REG_MASKA,
- FUSB_REG_MASKA_TOGDONE);
diff --git a/sys-kernel/pinephone-pro-sources/files/0024-usb-typec-typec-extcon-Add-typec-extcon-bridge-drive.patch b/sys-kernel/pinephone-pro-sources/files/0024-usb-typec-typec-extcon-Add-typec-extcon-bridge-drive.patch
deleted file mode 100644
index d8c007c..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0024-usb-typec-typec-extcon-Add-typec-extcon-bridge-drive.patch
+++ /dev/null
@@ -1,388 +0,0 @@
-From: Ondrej Jirman
-Date: Sun, 7 Nov 2021 19:24:40 +0100
-Subject: [PATCH 35/36] usb: typec: typec-extcon: Add typec -> extcon bridge
- driver
-
-This bridge connects standard Type C port interfaces for controling
-muxes, switches and usb roles to muxes, switches and usb role
-drivers controlled via extcon interface.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/usb/typec/Kconfig | 7 +
- drivers/usb/typec/Makefile | 1 +
- drivers/usb/typec/typec-extcon.c | 337 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 345 insertions(+)
- create mode 100644 drivers/usb/typec/typec-extcon.c
-
-diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
-index ab480f3..01ecc5e 100644
---- a/drivers/usb/typec/Kconfig
-+++ b/drivers/usb/typec/Kconfig
-@@ -88,6 +88,13 @@ config TYPEC_QCOM_PMIC
- It will also enable the VBUS output to connected devices when a
- DFP connection is made.
-
-+config TYPEC_EXTCON
-+ tristate "Type-C switch/mux -> extcon interface bridge driver"
-+ depends on USB_ROLE_SWITCH
-+ help
-+ Say Y or M here if your system needs bridging between typec class
-+ and extcon interfaces.
-+
- source "drivers/usb/typec/mux/Kconfig"
-
- source "drivers/usb/typec/altmodes/Kconfig"
-diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
-index a0adb89..d9d8293 100644
---- a/drivers/usb/typec/Makefile
-+++ b/drivers/usb/typec/Makefile
-@@ -8,4 +8,5 @@ obj-$(CONFIG_TYPEC_TPS6598X) += tipd/
- obj-$(CONFIG_TYPEC_HD3SS3220) += hd3ss3220.o
- obj-$(CONFIG_TYPEC_QCOM_PMIC) += qcom-pmic-typec.o
- obj-$(CONFIG_TYPEC_STUSB160X) += stusb160x.o
-+obj-$(CONFIG_TYPEC_EXTCON) += typec-extcon.o
- obj-$(CONFIG_TYPEC) += mux/
-diff --git a/drivers/usb/typec/typec-extcon.c b/drivers/usb/typec/typec-extcon.c
-new file mode 100644
-index 00000000..143ff24
---- /dev/null
-+++ b/drivers/usb/typec/typec-extcon.c
-@@ -0,0 +1,337 @@
-+/*
-+ * typec -> extcon bridge
-+ * Copyright (c) 2021 Ondřej Jirman
-+ *
-+ * This driver bridges standard type-c interfaces to drivers that
-+ * expect extcon interface.
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+struct typec_extcon {
-+ struct device *dev;
-+
-+ /* consumers */
-+ struct usb_role_switch *role_sw;
-+ struct typec_switch *sw;
-+ struct typec_mux *mux;
-+
-+ /* providers */
-+ struct extcon_dev *extcon;
-+ struct notifier_block extcon_nb;
-+
-+ /* cached state from typec controller */
-+ enum usb_role role;
-+ enum typec_orientation orientation;
-+ struct typec_altmode alt;
-+ unsigned long mode;
-+ bool has_alt;
-+ struct mutex lock;
-+};
-+
-+static const unsigned int typec_extcon_cable[] = {
-+ EXTCON_DISP_DP,
-+
-+ EXTCON_USB,
-+ EXTCON_USB_HOST,
-+
-+ EXTCON_CHG_USB_SDP,
-+ EXTCON_CHG_USB_CDP,
-+ EXTCON_CHG_USB_DCP,
-+ EXTCON_CHG_USB_ACA,
-+
-+ EXTCON_NONE,
-+};
-+
-+static void typec_extcon_set_cable(struct typec_extcon *tce, int id, bool on,
-+ union extcon_property_value prop_ss,
-+ union extcon_property_value prop_or)
-+{
-+ union extcon_property_value cur_ss, cur_or;
-+ bool prop_diff = false;
-+ int ret;
-+
-+ ret = extcon_get_property(tce->extcon, id,
-+ EXTCON_PROP_USB_SS, &cur_ss);
-+ if (ret || cur_ss.intval != prop_ss.intval)
-+ prop_diff = true;
-+
-+ ret = extcon_get_property(tce->extcon, id,
-+ EXTCON_PROP_USB_TYPEC_POLARITY, &cur_or);
-+ if (ret || cur_or.intval != prop_or.intval)
-+ prop_diff = true;
-+
-+ if (!on && extcon_get_state(tce->extcon, id)) {
-+ extcon_set_state_sync(tce->extcon, id, false);
-+ } else if (on && (!extcon_get_state(tce->extcon, id) || prop_diff)) {
-+ extcon_set_state(tce->extcon, id, true);
-+ extcon_set_property(tce->extcon, id,
-+ EXTCON_PROP_USB_SS, prop_ss);
-+ extcon_set_property(tce->extcon, id,
-+ EXTCON_PROP_USB_TYPEC_POLARITY, prop_or);
-+ extcon_sync(tce->extcon, id);
-+ }
-+}
-+
-+static int typec_extcon_sync_extcon(struct typec_extcon *tce)
-+{
-+ union extcon_property_value prop_ss, prop_or;
-+ bool has_dp = false;
-+
-+ mutex_lock(&tce->lock);
-+
-+ /* connector is disconnected */
-+ if (tce->orientation == TYPEC_ORIENTATION_NONE) {
-+ typec_extcon_set_cable(tce, EXTCON_USB, false, prop_ss, prop_or);
-+ typec_extcon_set_cable(tce, EXTCON_USB_HOST, false, prop_ss, prop_or);
-+ typec_extcon_set_cable(tce, EXTCON_DISP_DP, false, prop_ss, prop_or);
-+
-+ extcon_set_state_sync(tce->extcon, EXTCON_CHG_USB_SDP, false);
-+ extcon_set_state_sync(tce->extcon, EXTCON_CHG_USB_DCP, false);
-+ extcon_set_state_sync(tce->extcon, EXTCON_CHG_USB_CDP, false);
-+ extcon_set_state_sync(tce->extcon, EXTCON_CHG_USB_ACA, false);
-+
-+ goto out_unlock;
-+ }
-+
-+ prop_or.intval = tce->orientation == TYPEC_ORIENTATION_NORMAL ? 0 : 1;
-+ prop_ss.intval = 0;
-+
-+ if (tce->has_alt && tce->alt.svid == USB_TYPEC_DP_SID) {
-+ switch (tce->mode) {
-+ case TYPEC_STATE_SAFE:
-+ break;
-+ case TYPEC_DP_STATE_C:
-+ case TYPEC_DP_STATE_E:
-+ has_dp = true;
-+ break;
-+ case TYPEC_DP_STATE_D:
-+ has_dp = true;
-+ fallthrough;
-+ case TYPEC_STATE_USB:
-+ prop_ss.intval = 1;
-+ break;
-+ default:
-+ dev_err(tce->dev, "unhandled mux mode=%lu\n", tce->mode);
-+ break;
-+ }
-+ }
-+
-+ typec_extcon_set_cable(tce, EXTCON_USB,
-+ tce->role == USB_ROLE_DEVICE, prop_ss, prop_or);
-+ typec_extcon_set_cable(tce, EXTCON_USB_HOST,
-+ tce->role == USB_ROLE_HOST, prop_ss, prop_or);
-+
-+ typec_extcon_set_cable(tce, EXTCON_DISP_DP, has_dp, prop_ss, prop_or);
-+
-+out_unlock:
-+ mutex_unlock(&tce->lock);
-+ return 0;
-+}
-+
-+static int typec_extcon_sw_set(struct typec_switch *sw,
-+ enum typec_orientation orientation)
-+{
-+ struct typec_extcon *tce = typec_switch_get_drvdata(sw);
-+
-+ dev_dbg(tce->dev, "SW SET: orientation=%d\n", orientation);
-+
-+ mutex_lock(&tce->lock);
-+ tce->orientation = orientation;
-+ mutex_unlock(&tce->lock);
-+
-+ typec_extcon_sync_extcon(tce);
-+
-+ return 0;
-+}
-+
-+static int typec_extcon_mux_set(struct typec_mux *mux,
-+ struct typec_mux_state *state)
-+{
-+ struct typec_extcon *tce = typec_mux_get_drvdata(mux);
-+ struct typec_altmode *alt = state->alt;
-+
-+ dev_dbg(tce->dev, "MUX SET: state->mode=%lu\n", state->mode);
-+ if (alt)
-+ dev_dbg(tce->dev, " ...alt: svid=%04hx mode=%d vdo=%08x active=%u\n",
-+ alt->svid, alt->mode, alt->vdo, alt->active);
-+
-+ mutex_lock(&tce->lock);
-+ tce->mode = state->mode;
-+ tce->has_alt = alt != NULL;
-+ if (alt)
-+ tce->alt = *alt;
-+ mutex_unlock(&tce->lock);
-+
-+ typec_extcon_sync_extcon(tce);
-+
-+ return 0;
-+}
-+
-+static int typec_extcon_usb_set_role(struct usb_role_switch *sw,
-+ enum usb_role role)
-+{
-+ struct typec_extcon *tce = usb_role_switch_get_drvdata(sw);
-+
-+ dev_dbg(tce->dev, "ROLE SET: role=%d\n", role);
-+
-+ mutex_lock(&tce->lock);
-+ tce->role = role;
-+ mutex_unlock(&tce->lock);
-+
-+ typec_extcon_sync_extcon(tce);
-+
-+ return 0;
-+}
-+
-+static int typec_extcon_notifier(struct notifier_block *nb,
-+ unsigned long action, void *data)
-+{
-+ struct typec_extcon *tce = container_of(nb, struct typec_extcon, extcon_nb);
-+
-+ bool sdp = extcon_get_state(tce->extcon, EXTCON_CHG_USB_SDP);
-+ bool cdp = extcon_get_state(tce->extcon, EXTCON_CHG_USB_CDP);
-+ bool dcp = extcon_get_state(tce->extcon, EXTCON_CHG_USB_DCP);
-+ bool usb = extcon_get_state(tce->extcon, EXTCON_USB);
-+ bool usb_host = extcon_get_state(tce->extcon, EXTCON_USB_HOST);
-+ bool dp = extcon_get_state(tce->extcon, EXTCON_DISP_DP);
-+
-+ dev_info(tce->dev, "extcon changed sdp=%d cdp=%d dcp=%d usb=%d usb_host=%d dp=%d\n",
-+ sdp, cdp, dcp, usb, usb_host, dp);
-+
-+ return NOTIFY_OK;
-+}
-+
-+static int typec_extcon_probe(struct platform_device *pdev)
-+{
-+ struct typec_switch_desc sw_desc = { };
-+ struct typec_mux_desc mux_desc = { };
-+ struct usb_role_switch_desc role_desc = { };
-+ struct device *dev = &pdev->dev;
-+ struct typec_extcon *tce;
-+ int ret = 0;
-+
-+ tce = devm_kzalloc(dev, sizeof(*tce), GFP_KERNEL);
-+ if (!tce)
-+ return -ENOMEM;
-+
-+ tce->dev = &pdev->dev;
-+ mutex_init(&tce->lock);
-+ tce->mode = TYPEC_STATE_SAFE;
-+
-+ sw_desc.drvdata = tce;
-+ sw_desc.fwnode = dev->fwnode;
-+ sw_desc.set = typec_extcon_sw_set;
-+
-+ tce->sw = typec_switch_register(dev, &sw_desc);
-+ if (IS_ERR(tce->sw))
-+ return dev_err_probe(dev, PTR_ERR(tce->sw),
-+ "Error registering typec switch\n");
-+
-+ mux_desc.drvdata = tce;
-+ mux_desc.fwnode = dev->fwnode;
-+ mux_desc.set = typec_extcon_mux_set;
-+
-+ tce->mux = typec_mux_register(dev, &mux_desc);
-+ if (IS_ERR(tce->mux)) {
-+ ret = dev_err_probe(dev, PTR_ERR(tce->mux),
-+ "Error registering typec mux\n");
-+ goto err_sw;
-+ }
-+
-+ role_desc.driver_data = tce;
-+ role_desc.fwnode = dev->fwnode;
-+ role_desc.name = fwnode_get_name(dev->fwnode);
-+ role_desc.set = typec_extcon_usb_set_role;
-+
-+ tce->role_sw = usb_role_switch_register(dev, &role_desc);
-+ if (IS_ERR(tce->role_sw)) {
-+ ret = dev_err_probe(dev, PTR_ERR(tce->role_sw),
-+ "Error registering USB role switch\n");
-+ goto err_mux;
-+ }
-+
-+ tce->extcon = devm_extcon_dev_allocate(dev, typec_extcon_cable);
-+ if (IS_ERR(tce->extcon)) {
-+ ret = PTR_ERR(tce->extcon);
-+ goto err_role;
-+ }
-+
-+ ret = devm_extcon_dev_register(dev, tce->extcon);
-+ if (ret) {
-+ ret = dev_err_probe(dev, ret, "failed to register extcon device\n");
-+ goto err_role;
-+ }
-+
-+ extcon_set_property_capability(tce->extcon, EXTCON_USB,
-+ EXTCON_PROP_USB_SS);
-+ extcon_set_property_capability(tce->extcon, EXTCON_USB,
-+ EXTCON_PROP_USB_TYPEC_POLARITY);
-+ extcon_set_property_capability(tce->extcon, EXTCON_USB_HOST,
-+ EXTCON_PROP_USB_SS);
-+ extcon_set_property_capability(tce->extcon, EXTCON_USB_HOST,
-+ EXTCON_PROP_USB_TYPEC_POLARITY);
-+ extcon_set_property_capability(tce->extcon, EXTCON_DISP_DP,
-+ EXTCON_PROP_USB_SS);
-+ extcon_set_property_capability(tce->extcon, EXTCON_DISP_DP,
-+ EXTCON_PROP_USB_TYPEC_POLARITY);
-+
-+ tce->extcon_nb.notifier_call = typec_extcon_notifier;
-+ ret = devm_extcon_register_notifier_all(dev, tce->extcon, &tce->extcon_nb);
-+ if (ret) {
-+ dev_err_probe(dev, ret, "Failed to register extcon notifier\n");
-+ goto err_role;
-+ }
-+
-+ return 0;
-+
-+err_role:
-+ usb_role_switch_unregister(tce->role_sw);
-+err_mux:
-+ typec_mux_unregister(tce->mux);
-+err_sw:
-+ typec_switch_unregister(tce->sw);
-+ return ret;
-+}
-+
-+static int typec_extcon_remove(struct platform_device *pdev)
-+{
-+ struct typec_extcon *tce = platform_get_drvdata(pdev);
-+
-+ usb_role_switch_unregister(tce->role_sw);
-+ typec_mux_unregister(tce->mux);
-+ typec_switch_unregister(tce->sw);
-+
-+ return 0;
-+}
-+
-+static struct of_device_id typec_extcon_of_match_table[] = {
-+ { .compatible = "linux,typec-extcon-bridge" },
-+ { },
-+};
-+MODULE_DEVICE_TABLE(of, typec_extcon_of_match_table);
-+
-+static struct platform_driver typec_extcon_driver = {
-+ .driver = {
-+ .name = "typec-extcon",
-+ .of_match_table = typec_extcon_of_match_table,
-+ },
-+ .probe = typec_extcon_probe,
-+ .remove = typec_extcon_remove,
-+};
-+
-+module_platform_driver(typec_extcon_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Ondrej Jirman ");
-+MODULE_DESCRIPTION("typec -> extcon bridge driver");
diff --git a/sys-kernel/pinephone-pro-sources/files/0025-phy-rockchip-typec-Make-sure-the-plug-orientation-is.patch b/sys-kernel/pinephone-pro-sources/files/0025-phy-rockchip-typec-Make-sure-the-plug-orientation-is.patch
deleted file mode 100644
index abb3c5c..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0025-phy-rockchip-typec-Make-sure-the-plug-orientation-is.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From: Ondrej Jirman
-Date: Tue, 23 Nov 2021 17:32:18 +0100
-Subject: [PATCH 36/36] phy: rockchip-typec: Make sure the plug orientation is
- respected
-
-RK3399 TRM says about bit 8:
-
-typec_conn_dir_sel: TypeC connect direction select
-
-- 0: select typec_conn_dir (bit0 of this register) to TypeC PHY
-- 1: select TCPC ouput typec_con_dir to TypeC PHY (default value)
-
-This means that by default, typec_conn_dir bit is not respected.
-Fix setting of typec_conn_dir by setting typec_conn_dir to 0 first.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/phy/rockchip/phy-rockchip-typec.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
-index d2bbdc9..fa10ee9 100644
---- a/drivers/phy/rockchip/phy-rockchip-typec.c
-+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
-@@ -350,6 +350,7 @@ struct usb3phy_reg {
- * struct rockchip_usb3phy_port_cfg - usb3-phy port configuration.
- * @reg: the base address for usb3-phy config.
- * @typec_conn_dir: the register of type-c connector direction.
-+ * @typec_conn_dir_sel: the register of type-c connector direction source.
- * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
- * @external_psm: the register of type-c phy external psm clock.
- * @pipe_status: the register of type-c phy pipe status.
-@@ -360,6 +361,7 @@ struct usb3phy_reg {
- struct rockchip_usb3phy_port_cfg {
- unsigned int reg;
- struct usb3phy_reg typec_conn_dir;
-+ struct usb3phy_reg typec_conn_dir_sel;
- struct usb3phy_reg usb3tousb2_en;
- struct usb3phy_reg external_psm;
- struct usb3phy_reg pipe_status;
-@@ -434,6 +436,7 @@ static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
- {
- .reg = 0xff7c0000,
- .typec_conn_dir = { 0xe580, 0, 16 },
-+ .typec_conn_dir_sel = { 0xe580, 8, 16+8 },
- .usb3tousb2_en = { 0xe580, 3, 19 },
- .external_psm = { 0xe588, 14, 30 },
- .pipe_status = { 0xe5c0, 0, 0 },
-@@ -444,6 +447,7 @@ static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
- {
- .reg = 0xff800000,
- .typec_conn_dir = { 0xe58c, 0, 16 },
-+ .typec_conn_dir_sel = { 0xe58c, 8, 16+8 },
- .usb3tousb2_en = { 0xe58c, 3, 19 },
- .external_psm = { 0xe594, 14, 30 },
- .pipe_status = { 0xe5c0, 16, 16 },
-@@ -739,6 +743,7 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
-
- reset_control_deassert(tcphy->tcphy_rst);
-
-+ property_enable(tcphy, &cfg->typec_conn_dir_sel, 0);
- property_enable(tcphy, &cfg->typec_conn_dir, tcphy->flip);
- tcphy_dp_aux_set_flip(tcphy);
-
diff --git a/sys-kernel/pinephone-pro-sources/files/0026-media-i2c-imx258-Add-support-for-powerdown-gpio.patch b/sys-kernel/pinephone-pro-sources/files/0026-media-i2c-imx258-Add-support-for-powerdown-gpio.patch
deleted file mode 100644
index 6d20e9e..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0026-media-i2c-imx258-Add-support-for-powerdown-gpio.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From: Ondrej Jirman
-Date: Fri, 22 Oct 2021 18:10:18 +0200
-Subject: [PATCH 20/36] media: i2c: imx258: Add support for powerdown gpio
-
-On some boards powerdown signal needs to be deasserted for this
-sensor to be enabled.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/media/i2c/imx258.c | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
-diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
-index c249507..be5adcc 100644
---- a/drivers/media/i2c/imx258.c
-+++ b/drivers/media/i2c/imx258.c
-@@ -612,6 +612,8 @@ struct imx258 {
- struct v4l2_ctrl *hblank;
- struct v4l2_ctrl *exposure;
-
-+ struct gpio_desc *pwdn_gpio;
-+
- /* Current mode */
- const struct imx258_mode *cur_mode;
-
-@@ -1010,6 +1012,8 @@ static int imx258_power_on(struct device *dev)
- struct imx258 *imx258 = to_imx258(sd);
- int ret;
-
-+ gpiod_set_value_cansleep(imx258->pwdn_gpio, 0);
-+
- ret = clk_prepare_enable(imx258->clk);
- if (ret)
- dev_err(dev, "failed to enable clock\n");
-@@ -1024,6 +1028,8 @@ static int imx258_power_off(struct device *dev)
-
- clk_disable_unprepare(imx258->clk);
-
-+ gpiod_set_value_cansleep(imx258->pwdn_gpio, 1);
-+
- return 0;
- }
-
-@@ -1284,6 +1290,12 @@ static int imx258_probe(struct i2c_client *client)
- if (ret || val != 180)
- return -EINVAL;
-
-+ /* request optional power down pin */
-+ imx258->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
-+ GPIOD_OUT_HIGH);
-+ if (IS_ERR(imx258->pwdn_gpio))
-+ return PTR_ERR(imx258->pwdn_gpio);
-+
- /* Initialize subdev */
- v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);
-
diff --git a/sys-kernel/pinephone-pro-sources/files/0027-media-i2c-imx258-Don-t-be-too-strict-about-clock-rat.patch b/sys-kernel/pinephone-pro-sources/files/0027-media-i2c-imx258-Don-t-be-too-strict-about-clock-rat.patch
deleted file mode 100644
index ef345ec..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0027-media-i2c-imx258-Don-t-be-too-strict-about-clock-rat.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From: Ondrej Jirman
-Date: Fri, 22 Oct 2021 18:11:26 +0200
-Subject: [PATCH 21/36] media: i2c: imx258: Don't be too strict about clock
- rate
-
-On Pinephone Pro, we are not able to set 19.2MHz precisely.
-Allow some slack in clock rate.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/media/i2c/imx258.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
-index be5adcc..e64fadc 100644
---- a/drivers/media/i2c/imx258.c
-+++ b/drivers/media/i2c/imx258.c
-@@ -79,7 +79,9 @@
- #define REG_CONFIG_FLIP_TEST_PATTERN 0x02
-
- /* Input clock frequency in Hz */
-+#define IMX258_INPUT_CLOCK_FREQ_MIN 19000000
- #define IMX258_INPUT_CLOCK_FREQ 19200000
-+#define IMX258_INPUT_CLOCK_FREQ_MAX 19400000
-
- struct imx258_reg {
- u16 address;
-@@ -1277,8 +1279,11 @@ static int imx258_probe(struct i2c_client *client)
- } else {
- val = clk_get_rate(imx258->clk);
- }
-- if (val != IMX258_INPUT_CLOCK_FREQ) {
-- dev_err(&client->dev, "input clock frequency not supported\n");
-+
-+ if (val < IMX258_INPUT_CLOCK_FREQ_MIN
-+ || val > IMX258_INPUT_CLOCK_FREQ_MAX) {
-+ dev_err(&client->dev, "input clock frequency %u not supported\n",
-+ val);
- return -EINVAL;
- }
-
diff --git a/sys-kernel/pinephone-pro-sources/files/0028-media-i2c-imx258-Add-support-for-reset-gpio.patch b/sys-kernel/pinephone-pro-sources/files/0028-media-i2c-imx258-Add-support-for-reset-gpio.patch
deleted file mode 100644
index af85962..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0028-media-i2c-imx258-Add-support-for-reset-gpio.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From: Ondrej Jirman
-Date: Fri, 22 Oct 2021 21:44:13 +0200
-Subject: [PATCH 22/36] media: i2c: imx258: Add support for reset gpio
-
-It was documented in DT, but not implemented.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/media/i2c/imx258.c | 14 +++++++++++++-
- 1 file changed, 13 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
-index e64fadc..ec6e919 100644
---- a/drivers/media/i2c/imx258.c
-+++ b/drivers/media/i2c/imx258.c
-@@ -615,6 +615,7 @@ struct imx258 {
- struct v4l2_ctrl *exposure;
-
- struct gpio_desc *pwdn_gpio;
-+ struct gpio_desc *reset_gpio;
-
- /* Current mode */
- const struct imx258_mode *cur_mode;
-@@ -1020,7 +1021,11 @@ static int imx258_power_on(struct device *dev)
- if (ret)
- dev_err(dev, "failed to enable clock\n");
-
-- return ret;
-+ gpiod_set_value_cansleep(imx258->reset_gpio, 0);
-+
-+ usleep_range(400, 500);
-+
-+ return 0;
- }
-
- static int imx258_power_off(struct device *dev)
-@@ -1030,6 +1035,7 @@ static int imx258_power_off(struct device *dev)
-
- clk_disable_unprepare(imx258->clk);
-
-+ gpiod_set_value_cansleep(imx258->reset_gpio, 1);
- gpiod_set_value_cansleep(imx258->pwdn_gpio, 1);
-
- return 0;
-@@ -1301,6 +1307,12 @@ static int imx258_probe(struct i2c_client *client)
- if (IS_ERR(imx258->pwdn_gpio))
- return PTR_ERR(imx258->pwdn_gpio);
-
-+ /* request optional reset pin */
-+ imx258->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
-+ GPIOD_OUT_HIGH);
-+ if (IS_ERR(imx258->reset_gpio))
-+ return PTR_ERR(imx258->reset_gpio);
-+
- /* Initialize subdev */
- v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);
-
diff --git a/sys-kernel/pinephone-pro-sources/files/0029-media-i2c-imx258-Add-support-for-power-supplies.patch b/sys-kernel/pinephone-pro-sources/files/0029-media-i2c-imx258-Add-support-for-power-supplies.patch
deleted file mode 100644
index 23c09d8..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0029-media-i2c-imx258-Add-support-for-power-supplies.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From: Ondrej Jirman
-Date: Fri, 22 Oct 2021 21:44:30 +0200
-Subject: [PATCH 23/36] media: i2c: imx258: Add support for power supplies
-
-They were documented in DT, but not implemented.
-
-Signed-off-by: Ondrej Jirman
----
- drivers/media/i2c/imx258.c | 39 +++++++++++++++++++++++++++++++++++++--
- 1 file changed, 37 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
-index ec6e919..2570b51 100644
---- a/drivers/media/i2c/imx258.c
-+++ b/drivers/media/i2c/imx258.c
-@@ -602,6 +602,15 @@ static const struct imx258_mode supported_modes[] = {
- },
- };
-
-+/* regulator supplies */
-+static const char * const imx258_supply_names[] = {
-+ "vana", /* Analog (2.8V) supply */
-+ "vdig", /* Digital Core (1.5V) supply */
-+ "vif", /* Digital I/O (1.8V) supply */
-+};
-+
-+#define IMX258_SUPPLY_COUNT ARRAY_SIZE(imx258_supply_names)
-+
- struct imx258 {
- struct v4l2_subdev sd;
- struct media_pad pad;
-@@ -616,6 +625,7 @@ struct imx258 {
-
- struct gpio_desc *pwdn_gpio;
- struct gpio_desc *reset_gpio;
-+ struct regulator_bulk_data supplies[IMX258_SUPPLY_COUNT];
-
- /* Current mode */
- const struct imx258_mode *cur_mode;
-@@ -1015,11 +1025,26 @@ static int imx258_power_on(struct device *dev)
- struct imx258 *imx258 = to_imx258(sd);
- int ret;
-
-+ ret = regulator_bulk_enable(IMX258_SUPPLY_COUNT, imx258->supplies);
-+ if (ret) {
-+ dev_err(dev, "failed to enable regulators\n");
-+ return ret;
-+ }
-+
-+ mdelay(20);
-+
- gpiod_set_value_cansleep(imx258->pwdn_gpio, 0);
-
-+ mdelay(5);
-+
- ret = clk_prepare_enable(imx258->clk);
-- if (ret)
-+ if (ret) {
- dev_err(dev, "failed to enable clock\n");
-+ regulator_bulk_disable(IMX258_SUPPLY_COUNT, imx258->supplies);
-+ return ret;
-+ }
-+
-+ usleep_range(1000, 2000);
-
- gpiod_set_value_cansleep(imx258->reset_gpio, 0);
-
-@@ -1038,6 +1063,8 @@ static int imx258_power_off(struct device *dev)
- gpiod_set_value_cansleep(imx258->reset_gpio, 1);
- gpiod_set_value_cansleep(imx258->pwdn_gpio, 1);
-
-+ regulator_bulk_disable(IMX258_SUPPLY_COUNT, imx258->supplies);
-+
- return 0;
- }
-
-@@ -1266,7 +1293,7 @@ static void imx258_free_controls(struct imx258 *imx258)
- static int imx258_probe(struct i2c_client *client)
- {
- struct imx258 *imx258;
-- int ret;
-+ int ret, i;
- u32 val = 0;
-
- imx258 = devm_kzalloc(&client->dev, sizeof(*imx258), GFP_KERNEL);
-@@ -1301,6 +1328,14 @@ static int imx258_probe(struct i2c_client *client)
- if (ret || val != 180)
- return -EINVAL;
-
-+ for (i = 0; i < IMX258_SUPPLY_COUNT; i++)
-+ imx258->supplies[i].supply = imx258_supply_names[i];
-+ ret = devm_regulator_bulk_get(&client->dev,
-+ IMX258_SUPPLY_COUNT,
-+ imx258->supplies);
-+ if (ret)
-+ return dev_err_probe(&client->dev, ret, "Failed to get supplies\n");
-+
- /* request optional power down pin */
- imx258->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
- GPIOD_OUT_HIGH);
diff --git a/sys-kernel/pinephone-pro-sources/files/0030-drm-panel-hx8394-Add-driver-for-HX8394-based-HannSta.patch b/sys-kernel/pinephone-pro-sources/files/0030-drm-panel-hx8394-Add-driver-for-HX8394-based-HannSta.patch
deleted file mode 100644
index fc6634b..0000000
--- a/sys-kernel/pinephone-pro-sources/files/0030-drm-panel-hx8394-Add-driver-for-HX8394-based-HannSta.patch
+++ /dev/null
@@ -1,464 +0,0 @@
-From: =?utf-8?q?Kamil_Trzci=C5=84ski?=
-Date: Wed, 8 Sep 2021 13:50:04 +0200
-Subject: [PATCH 05/36] drm: panel: hx8394: Add driver for HX8394 based
- HannStar HSD060BHW4 panel
-MIME-Version: 1.0
-Content-Type: text/plain; charset="utf-8"
-Content-Transfer-Encoding: 8bit
-
-...
-
-Signed-off-by: Kamil Trzciński
-Signed-off-by: Ondrej Jirman
----
- drivers/gpu/drm/panel/Kconfig | 9 +
- drivers/gpu/drm/panel/Makefile | 1 +
- drivers/gpu/drm/panel/panel-himax-hx8394.c | 410 +++++++++++++++++++++++++++++
- 3 files changed, 420 insertions(+)
- create mode 100644 drivers/gpu/drm/panel/panel-himax-hx8394.c
-
-diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
-index cfc8d64..166bd4a 100644
---- a/drivers/gpu/drm/panel/Kconfig
-+++ b/drivers/gpu/drm/panel/Kconfig
-@@ -129,6 +129,15 @@ config DRM_PANEL_FEIYANG_FY07024DI26A30D
- Say Y if you want to enable support for panels based on the
- Feiyang FY07024DI26A30-D MIPI-DSI interface.
-
-+config DRM_PANEL_HIMAX_HX8394
-+ tristate "HIMAX HX8394 MIPI-DSI LCD panel"
-+ depends on OF
-+ depends on DRM_MIPI_DSI
-+ depends on BACKLIGHT_CLASS_DEVICE
-+ help
-+ Say Y if you want to enable support for panels based on the
-+ HIMAX HX8394 MIPI-DSI interface.
-+
- config DRM_PANEL_ILITEK_IL9322
- tristate "Ilitek ILI9322 320x240 QVGA panels"
- depends on OF && SPI
-diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
-index bca4cc1..486926c 100644
---- a/drivers/gpu/drm/panel/Makefile
-+++ b/drivers/gpu/drm/panel/Makefile
-@@ -67,3 +67,4 @@ obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
- obj-$(CONFIG_DRM_PANEL_VISIONOX_RM69299) += panel-visionox-rm69299.o
- obj-$(CONFIG_DRM_PANEL_WIDECHIPS_WS2401) += panel-widechips-ws2401.o
- obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o
-+obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o
-diff --git a/drivers/gpu/drm/panel/panel-himax-hx8394.c b/drivers/gpu/drm/panel/panel-himax-hx8394.c
-new file mode 100644
-index 00000000..14659cb
---- /dev/null
-+++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c
-@@ -0,0 +1,410 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Driver for panels based on Himax HX8394 controller, souch as:
-+ *
-+ * - HannStar HSD060BHW4 5.99" MIPI-DSI panel
-+ *
-+ * Copyright (C) Kamil Trzciński
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include