Merge pull request #2995 from r3claimer/dev

ACE - rollback kernel to 5.10
This commit is contained in:
r3claimer 2024-03-07 06:14:28 -08:00 committed by GitHub
commit ffcb03eb45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 1136 additions and 3826 deletions

View file

@ -33,7 +33,7 @@ This document describes all available systems emulators and cores available for
|Capcom|CPS-I (cps1)|1988|`cps1`|.zip .7z|**retroarch:** fbneo (default)<br>**retroarch:** mame2003_plus<br>**retroarch:** mame2010<br>**retroarch:** fbalpha2012<br>**AdvanceMame:** AdvanceMame<br>|
|Capcom|CPS-II (cps2)|1993|`cps2`|.zip .7z|**retroarch:** fbneo (default)<br>**retroarch:** mame2003_plus<br>**retroarch:** mame2010<br>**retroarch:** fbalpha2012<br>**AdvanceMame:** AdvanceMame<br>|
|Capcom|CPS-III (cps3)|1996|`cps3`|.zip .7z|**retroarch:** fbneo (default)<br>**retroarch:** mame2003_plus<br>**retroarch:** mame2010<br>**retroarch:** fbalpha2012<br>**AdvanceMame:** AdvanceMame<br>|
|Coleco|ColecoVision (colecovision)|1982|`coleco`|.bin .col .rom .zip .7z|**retroarch:** bluemsx (default)<br>**retroarch:** gearcoleco<br>**retroarch:** smsplus<br>|
|Coleco|ColecoVision (colecovision)|1982|`coleco`|.bin .col .rom .zip .7z|**retroarch:** gearcoleco (default)<br>**retroarch:** bluemsx<br>**retroarch:** smsplus<br>|
|Commodore|Amiga (amiga)|1985|`amiga`|.zip .adf .uae .ipf .dms .adz .lha .m3u .hdf .hdz|**retroarch:** puae2021 (default)<br>**retroarch:** puae<br>**amiberry:** amiberry<br>**retroarch:** uae4arm<br>|
|Commodore|Amiga CD32 (amigacd32)|1994|`amigacd32`|.iso .cue .lha .chd|**retroarch:** puae2021 (default)<br>**retroarch:** puae<br>**retroarch:** uae4arm<br>|
|Commodore|Commodore 128 (c128)|1985|`c128`|.d64 .d71 .d80 .d81 .d82 .g64 .g41 .x64 .t64 .tap .prg .p00 .crt .bin .d6z .d7z .d8z .g6z .g4z .x6z .cmd .m3u .vsf .nib .nbz .zip|**retroarch:** vice_x128 (default)<br>**vicesa:** x128<br>|
@ -116,6 +116,7 @@ This document describes all available systems emulators and cores available for
|Sony|PlayStation Portable (psp)|2004|`psp`|.iso .cso .pbp .chd|**ppsspp:** ppsspp-sa (default)<br>|
|Sony|PSP Minis (pspminis)|2004|`pspminis`|.iso .cso .pbp|**ppsspp:** ppsspp-sa (default)<br>**retroarch:** ppsspp<br>|
|Sun Microsystems|J2ME (j2me)|2002|`j2me`|.jar|**retroarch:** freej2me (default)<br>|
|Thomson|MO/TO family (TO7, TO7/70, TO8, TO8D, TO9, TO9+, MO5 and MO6) (moto)|1982|`moto`|.fd .sap .k7 .m7 .m5 .rom|**retroarch:** theodore (default)<br>|
|Various|CHIP-8 / S-CHIP / XO-CHIP (chip-8)|1978|`chip-8`|.ch8 .sc8 .xo8|**retroarch:** jaxe (default)<br>|
|Various|EasyRPG (easyrpg)|2003|`easyrpg`|.zip .easyrpg .ldb|**retroarch:** easyrpg (default)<br>|
|Various|OpenBOR (openbor)|2003|`openbor`|.pak|**OpenBOR:** OpenBOR (default)<br>|

View file

@ -5,4 +5,5 @@
cat <<EOF >/storage/.config/profile.d/010-governors
CPU_FREQ=("/sys/devices/system/cpu/cpufreq/policy0" "/sys/devices/system/cpu/cpufreq/policy4" "/sys/devices/system/cpu/cpufreq/policy6")
GPU_FREQ=("/sys/devices/platform/fb000000.gpu/devfreq/fb000000.gpu")
DMC_FREQ=("/sys/devices/platform/dmc/devfreq/dmc")
EOF

View file

@ -22,9 +22,9 @@ case ${DEVICE} in
PKG_GIT_CLONE_BRANCH="main"
;;
RK3588-ACE)
PKG_VERSION="99e54e1a546eca7fa8d5b86be1b825914e097d06"
PKG_URL="https://github.com/JustEnoughLinuxOS/linux-rockchip/archive/${PKG_VERSION}.tar.gz"
PKG_GIT_CLONE_BRANCH="panfork-6.1"
PKG_VERSION="8f20ea790638c80f3913b0e66d90800591a824c3"
PKG_URL="https://github.com/armbian/linux-rockchip/archive/${PKG_VERSION}.tar.gz"
PKG_GIT_CLONE_BRANCH="rk-5.10-rkr6"
;;
RK356*)
PKG_VERSION="6.8-rc6"

View file

@ -29,7 +29,7 @@ get_graphicdrivers
PKG_FFMPEG_HWACCEL="--enable-hwaccels"
case ${DEVICE} in
RK3588)
RK3588*)
V4L2_SUPPORT=no
;;
*)

File diff suppressed because it is too large Load diff

View file

@ -13,9 +13,8 @@ PKG_PATCH_DIRS+="${DEVICE}"
case ${DEVICE} in
RK358*)
PKG_URL="${PKG_SITE}/rk35xx-uboot.git"
PKG_VERSION="d34ff0716"
PKG_GIT_CLONE_BRANCH="v2017.09-rk3588"
PKG_URL="${PKG_SITE}/rk35xx-uboot/archive/${PKG_VERSION}.tar.gz"
;;
RK356*)
PKG_URL="https://github.com/u-boot/u-boot.git"

View file

@ -1,8 +1,7 @@
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 364768ec4f47..2918159ddb4e 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -313,6 +313,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-evb4-lp4x-v10.dtb
diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/Makefile linux/arch/arm64/boot/dts/rockchip/Makefile
--- linux.orig/arch/arm64/boot/dts/rockchip/Makefile 2024-03-06 16:57:38.191015550 +0000
+++ linux/arch/arm64/boot/dts/rockchip/Makefile 2024-03-06 16:59:03.441724317 +0000
@@ -285,6 +285,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-e
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-evb4-lp4x-v10-linux.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-evb8-lp4x-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-9tripod-linux.dtb
@ -10,154 +9,9 @@ index 364768ec4f47..2918159ddb4e 100644
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-khadas-edge2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-lubancat-4.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6c.dtb
diff --git a/arch/arm64/boot/dts/rockchip/lcd-hx8399c_mipi.dtsi b/arch/arm64/boot/dts/rockchip/lcd-hx8399c_mipi.dtsi
new file mode 100644
index 000000000000..af4a6c170200
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/lcd-hx8399c_mipi.dtsi
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+&dsi0 {
+ status = "okay";
+ //rockchip,lane-rate = <1000>;
+ dsi0_panel: panel@0 {
+ status = "okay";
+ compatible = "simple-panel-dsi";
+ reg = <0>;
+ backlight = <&backlight>;
+ reset-delay-ms = <120>;
+ enable-delay-ms = <120>;
+ init-delay-ms = <120>;
+ stbyb-delay-ms = <120>;
+ prepare-delay-ms = <120>;
+ unprepare-delay-ms = <120>;
+ rotation = <90>;
+ disable-delay-ms = <120>;
+ dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;
+ dsi,format = <MIPI_DSI_FMT_RGB888>;
+ dsi,lanes = <4>;
+ //width-mm = <68>;
+ //height-mm = <120>;
+ panel-init-sequence = [
+ 39 00 04 B9 FF 83 99
+ 15 00 02 D2 77
+ 39 00 10 B1 02 04 74 94 01 32 33 11 11 AB 4D 56 73 02 02
+ 39 00 10 B2 00 80 80 AE 05 07 5A 11 00 00 10 1E 70 03 D4
+ 39 00 2d B4 00 FF 02 C0 02 C0 00 00 08 00 04 06 00 32 04 0A 08 21 03 01 00 0F B8 8B 02 C0 02 C0 00 00 08 00 04 06 00 32 04 0A 08 01 00 0F B8 01
+ 39 00 22 D3 00 00 00 00 00 00 06 00 00 10 04 00 04 00 00 00 00 00 00 00 00 00 00 01 00 05 05 07 00 00 00 05 40
+ 39 00 21 D5 18 18 19 19 18 18 21 20 01 00 07 06 05 04 03 02 18 18 18 18 18 18 2F 2F 30 30 31 31 18 18 18 18
+ 39 00 21 D6 18 18 19 19 40 40 20 21 02 03 04 05 06 07 00 01 40 40 40 40 40 40 2F 2F 30 30 31 31 40 40 40 40
+ 39 00 11 D8 A2 AA 02 A0 A2 A8 02 A0 B0 00 00 00 B0 00 00 00
+ 15 00 02 BD 01
+ 39 00 11 D8 B0 00 00 00 B0 00 00 00 E2 AA 03 F0 E2 AA 03 F0
+ 15 00 02 BD 02
+ 39 00 09 D8 E2 AA 03 F0 E2 AA 03 F0
+ 15 00 02 BD 00
+ 39 00 03 B6 7A 7A
+ 39 00 37 E0 00 18 27 24 5A 68 79 78 81 8A 92 99 9E A7 AF B4 B9 C3 C7 D1 C6 D4 D5 6C 67 71 77 00 00 18 27 24 5A 68 79 78 81 8A 92 99 9E A7 AF B4 B9 C3 C7 D1 C6 D4 D5 6C 67 77
+ 39 00 03 C6 FF F9
+ 15 00 02 CC 08
+ 05 78 01 11
+ 05 14 01 29
+ ];
+
+ panel-exit-sequence = [
+ 05 00 01 28
+ 05 00 01 10
+ ];
+
+ disp_timings0: display-timings {
+ native-mode = <&dsi0_timing0>;
+ dsi0_timing0: timing0 {
+ clock-frequency = <134920000>;
+ hactive = <1080>;
+ vactive = <1920>;
+ hfront-porch = <32>;
+ hsync-len = <8>;
+ hback-porch = <32>;
+ vfront-porch = <16>;
+ vsync-len = <2>;
+ vback-porch = <14>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <0>;
+ pixelclk-active = <1>;
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ panel_in_dsi: endpoint {
+ remote-endpoint = <&dsi_out_panel>;
+ };
+ };
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+ dsi_out_panel: endpoint {
+ remote-endpoint = <&panel_in_dsi>;
+ };
+ };
+ };
+
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
new file mode 100644
index 000000000000..84eeaef5f066
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts linux/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
--- linux.orig/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts 1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts 2024-03-06 16:58:28.748621788 +0000
@@ -0,0 +1,1409 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
@ -1305,11 +1159,11 @@ index 000000000000..84eeaef5f066
+&rknpu {
+ rknpu-supply = <&vdd_npu_s0>;
+ mem-supply = <&vdd_npu_mem_s0>;
+ status = "okay";
+ status = "disabled";
+};
+
+&rknpu_mmu {
+ status = "okay";
+ status = "disabled";
+};
+
+&rkvdec_ccu {

View file

@ -1,751 +0,0 @@
diff --git a/Makefile b/Makefile
index 7a238e4b489..c6fb4486752 100644
--- a/Makefile
+++ b/Makefile
@@ -518,7 +518,7 @@ LINUXINCLUDE := \
KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE
KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \
- -Werror=implicit-function-declaration -Werror=implicit-int \
+ -Werror=implicit-int \
-Werror=return-type -Wno-format-security \
-std=gnu89
KBUILD_CPPFLAGS := -D__KERNEL__
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index b9ecfffd9b0..62a52ccfe48 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -97,6 +97,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 833f3b52a9c..124445aba3f 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o
+obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o
obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.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 00000000000..f2ec6200484
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-himax-hx8394.c
@@ -0,0 +1,700 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for panels based on Himax HX8394 controller, such as:
+ *
+ * - HannStar HSD060BHW4 5.99" MIPI-DSI panel
+ *
+ * Copyright (C) 2021 Kamil Trzciński
+ *
+ * Based on drivers/gpu/drm/panel/panel-sitronix-st7703.c
+ * Copyright (C) Purism SPC 2019
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/media-bus-format.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+
+#define DRV_NAME "panel-himax-hx8394"
+
+/* Manufacturer specific commands sent via DSI, listed in HX8394-F datasheet */
+#define HX8394_CMD_SETSEQUENCE 0xb0
+#define HX8394_CMD_SETPOWER 0xb1
+#define HX8394_CMD_SETDISP 0xb2
+#define HX8394_CMD_SETCYC 0xb4
+#define HX8394_CMD_SETVCOM 0xb6
+#define HX8394_CMD_SETTE 0xb7
+#define HX8394_CMD_SETSENSOR 0xb8
+#define HX8394_CMD_SETEXTC 0xb9
+#define HX8394_CMD_SETMIPI 0xba
+#define HX8394_CMD_SETOTP 0xbb
+#define HX8394_CMD_SETREGBANK 0xbd
+#define HX8394_CMD_UNKNOWN5 0xbf
+#define HX8394_CMD_UNKNOWN1 0xc0
+#define HX8394_CMD_SETDGCLUT 0xc1
+#define HX8394_CMD_SETID 0xc3
+#define HX8394_CMD_SETDDB 0xc4
+#define HX8394_CMD_UNKNOWN2 0xc6
+#define HX8394_CMD_SETCABC 0xc9
+#define HX8394_CMD_SETCABCGAIN 0xca
+#define HX8394_CMD_SETPANEL 0xcc
+#define HX8394_CMD_SETOFFSET 0xd2
+#define HX8394_CMD_SETGIP0 0xd3
+#define HX8394_CMD_UNKNOWN3 0xd4
+#define HX8394_CMD_SETGIP1 0xd5
+#define HX8394_CMD_SETGIP2 0xd6
+#define HX8394_CMD_SETGPO 0xd6
+#define HX8394_CMD_UNKNOWN4 0xd8
+#define HX8394_CMD_SETGIP3 0xd8
+#define HX8394_CMD_SETSCALING 0xdd
+#define HX8394_CMD_SETIDLE 0xdf
+#define HX8394_CMD_SETGAMMA 0xe0
+#define HX8394_CMD_SETCHEMODE_DYN 0xe4
+#define HX8394_CMD_SETCHE 0xe5
+#define HX8394_CMD_SETCESEL 0xe6
+#define HX8394_CMD_SET_SP_CMD 0xe9
+#define HX8394_CMD_SETREADINDEX 0xfe
+#define HX8394_CMD_GETSPIREAD 0xff
+
+struct hx8394 {
+ struct device *dev;
+ struct drm_panel panel;
+ struct gpio_desc *reset_gpio;
+ struct regulator *vcc;
+ struct regulator *iovcc;
+
+ enum drm_panel_orientation orientation;
+
+ const struct hx8394_panel_desc *desc;
+};
+
+struct hx8394_panel_desc {
+ const struct drm_display_mode *mode;
+ unsigned int lanes;
+ unsigned long mode_flags;
+ enum mipi_dsi_pixel_format format;
+ int (*init_sequence)(struct hx8394 *ctx);
+};
+
+static inline struct hx8394 *panel_to_hx8394(struct drm_panel *panel)
+{
+ return container_of(panel, struct hx8394, panel);
+}
+
+static int hsd060bhw4_init_sequence(struct hx8394 *ctx)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+ /* 5.19.8 SETEXTC: Set extension command (B9h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETEXTC,
+ 0xff, 0x83, 0x94);
+
+ /* 5.19.2 SETPOWER: Set power (B1h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETPOWER,
+ 0x48, 0x11, 0x71, 0x09, 0x32, 0x24, 0x71, 0x31, 0x55, 0x30);
+
+ /* 5.19.9 SETMIPI: Set MIPI control (BAh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETMIPI,
+ 0x63, 0x03, 0x68, 0x6b, 0xb2, 0xc0);
+
+ /* 5.19.3 SETDISP: Set display related register (B2h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETDISP,
+ 0x00, 0x80, 0x78, 0x0c, 0x07);
+
+ /* 5.19.4 SETCYC: Set display waveform cycles (B4h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETCYC,
+ 0x12, 0x63, 0x12, 0x63, 0x12, 0x63, 0x01, 0x0c, 0x7c, 0x55,
+ 0x00, 0x3f, 0x12, 0x6b, 0x12, 0x6b, 0x12, 0x6b, 0x01, 0x0c,
+ 0x7c);
+
+ /* 5.19.19 SETGIP0: Set GIP Option0 (D3h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP0,
+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x1c, 0x00, 0x00, 0x32, 0x10,
+ 0x09, 0x00, 0x09, 0x32, 0x15, 0xad, 0x05, 0xad, 0x32, 0x00,
+ 0x00, 0x00, 0x00, 0x37, 0x03, 0x0b, 0x0b, 0x37, 0x00, 0x00,
+ 0x00, 0x0c, 0x40);
+
+ /* 5.19.20 Set GIP Option1 (D5h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP1,
+ 0x19, 0x19, 0x18, 0x18, 0x1b, 0x1b, 0x1a, 0x1a, 0x00, 0x01,
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x20, 0x21, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x24, 0x25, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18);
+
+ /* 5.19.21 Set GIP Option2 (D6h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP2,
+ 0x18, 0x18, 0x19, 0x19, 0x1b, 0x1b, 0x1a, 0x1a, 0x07, 0x06,
+ 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x25, 0x24, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x21, 0x20, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18);
+
+ /* 5.19.25 SETGAMMA: Set gamma curve related setting (E0h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGAMMA,
+ 0x00, 0x04, 0x0c, 0x12, 0x14, 0x18, 0x1a, 0x18, 0x31, 0x3f,
+ 0x4d, 0x4c, 0x54, 0x65, 0x6b, 0x70, 0x7f, 0x82, 0x7e, 0x8a,
+ 0x99, 0x4a, 0x48, 0x49, 0x4b, 0x4a, 0x4c, 0x4b, 0x7f, 0x00,
+ 0x04, 0x0c, 0x11, 0x13, 0x17, 0x1a, 0x18, 0x31,
+ 0x3f, 0x4d, 0x4c, 0x54, 0x65, 0x6b, 0x70, 0x7f,
+ 0x82, 0x7e, 0x8a, 0x99, 0x4a, 0x48, 0x49, 0x4b,
+ 0x4a, 0x4c, 0x4b, 0x7f);
+
+ /* 5.19.17 SETPANEL (CCh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETPANEL,
+ 0x0b);
+
+ /* Unknown command, not listed in the HX8394-F datasheet */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_UNKNOWN1,
+ 0x1f, 0x31);
+
+ /* 5.19.5 SETVCOM: Set VCOM voltage (B6h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETVCOM,
+ 0x7d, 0x7d);
+
+ /* Unknown command, not listed in the HX8394-F datasheet */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_UNKNOWN3,
+ 0x02);
+
+ /* 5.19.11 Set register bank (BDh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETREGBANK,
+ 0x01);
+
+ /* 5.19.2 SETPOWER: Set power (B1h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETPOWER,
+ 0x00);
+
+ /* 5.19.11 Set register bank (BDh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETREGBANK,
+ 0x00);
+
+ /* Unknown command, not listed in the HX8394-F datasheet */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_UNKNOWN3,
+ 0xed);
+
+ return 0;
+}
+
+static const struct drm_display_mode hsd060bhw4_mode = {
+ .hdisplay = 720,
+ .hsync_start = 720 + 40,
+ .hsync_end = 720 + 40 + 46,
+ .htotal = 720 + 40 + 46 + 40,
+ .vdisplay = 1440,
+ .vsync_start = 1440 + 9,
+ .vsync_end = 1440 + 9 + 7,
+ .vtotal = 1440 + 9 + 7 + 7,
+ .clock = 74250,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+ .width_mm = 68,
+ .height_mm = 136,
+};
+
+static const struct hx8394_panel_desc hsd060bhw4_desc = {
+ .mode = &hsd060bhw4_mode,
+ .lanes = 4,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST,
+ .format = MIPI_DSI_FMT_RGB888,
+ .init_sequence = hsd060bhw4_init_sequence,
+};
+
+static int powkiddy_x55_init_sequence(struct hx8394 *ctx)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+ /* 5.19.8 SETEXTC: Set extension command (B9h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETEXTC,
+ 0xff, 0x83, 0x94);
+
+ /* 5.19.9 SETMIPI: Set MIPI control (BAh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETMIPI,
+ 0x63, 0x03, 0x68, 0x6b, 0xb2, 0xc0);
+
+ /* 5.19.2 SETPOWER: Set power (B1h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETPOWER,
+ 0x48, 0x12, 0x72, 0x09, 0x32, 0x54, 0x71, 0x71, 0x57, 0x47);
+
+ /* 5.19.3 SETDISP: Set display related register (B2h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETDISP,
+ 0x00, 0x80, 0x64, 0x2c, 0x16, 0x2f);
+
+ /* 5.19.4 SETCYC: Set display waveform cycles (B4h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETCYC,
+ 0x73, 0x74, 0x73, 0x74, 0x73, 0x74, 0x01, 0x0c, 0x86, 0x75,
+ 0x00, 0x3f, 0x73, 0x74, 0x73, 0x74, 0x73, 0x74, 0x01, 0x0c,
+ 0x86);
+
+ /* 5.19.5 SETVCOM: Set VCOM voltage (B6h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETVCOM,
+ 0x6e, 0x6e);
+
+ /* 5.19.19 SETGIP0: Set GIP Option0 (D3h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP0,
+ 0x00, 0x00, 0x07, 0x07, 0x40, 0x07, 0x0c, 0x00, 0x08, 0x10,
+ 0x08, 0x00, 0x08, 0x54, 0x15, 0x0a, 0x05, 0x0a, 0x02, 0x15,
+ 0x06, 0x05, 0x06, 0x47, 0x44, 0x0a, 0x0a, 0x4b, 0x10, 0x07,
+ 0x07, 0x0c, 0x40);
+
+ /* 5.19.20 Set GIP Option1 (D5h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP1,
+ 0x1c, 0x1c, 0x1d, 0x1d, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x24, 0x25, 0x18, 0x18,
+ 0x26, 0x27, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x20, 0x21,
+ 0x18, 0x18, 0x18, 0x18);
+
+ /* 5.19.21 Set GIP Option2 (D6h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP2,
+ 0x1c, 0x1c, 0x1d, 0x1d, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
+ 0x01, 0x00, 0x0b, 0x0a, 0x09, 0x08, 0x21, 0x20, 0x18, 0x18,
+ 0x27, 0x26, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x25, 0x24,
+ 0x18, 0x18, 0x18, 0x18);
+
+ /* 5.19.25 SETGAMMA: Set gamma curve related setting (E0h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGAMMA,
+ 0x00, 0x0a, 0x15, 0x1b, 0x1e, 0x21, 0x24, 0x22, 0x47, 0x56,
+ 0x65, 0x66, 0x6e, 0x82, 0x88, 0x8b, 0x9a, 0x9d, 0x98, 0xa8,
+ 0xb9, 0x5d, 0x5c, 0x61, 0x66, 0x6a, 0x6f, 0x7f, 0x7f, 0x00,
+ 0x0a, 0x15, 0x1b, 0x1e, 0x21, 0x24, 0x22, 0x47, 0x56, 0x65,
+ 0x65, 0x6e, 0x81, 0x87, 0x8b, 0x98, 0x9d, 0x99, 0xa8, 0xba,
+ 0x5d, 0x5d, 0x62, 0x67, 0x6b, 0x72, 0x7f, 0x7f);
+
+ /* Unknown command, not listed in the HX8394-F datasheet */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_UNKNOWN1,
+ 0x1f, 0x31);
+
+ /* 5.19.17 SETPANEL (CCh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETPANEL,
+ 0x0b);
+
+ /* Unknown command, not listed in the HX8394-F datasheet */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_UNKNOWN3,
+ 0x02);
+
+ /* 5.19.11 Set register bank (BDh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETREGBANK,
+ 0x02);
+
+ /* Unknown command, not listed in the HX8394-F datasheet */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_UNKNOWN4,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff);
+
+ /* 5.19.11 Set register bank (BDh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETREGBANK,
+ 0x00);
+
+ /* 5.19.11 Set register bank (BDh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETREGBANK,
+ 0x01);
+
+ /* 5.19.2 SETPOWER: Set power (B1h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETPOWER,
+ 0x00);
+
+ /* 5.19.11 Set register bank (BDh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETREGBANK,
+ 0x00);
+
+ /* Unknown command, not listed in the HX8394-F datasheet */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_UNKNOWN5,
+ 0x40, 0x81, 0x50, 0x00, 0x1a, 0xfc, 0x01);
+
+ /* Unknown command, not listed in the HX8394-F datasheet */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_UNKNOWN2,
+ 0xed);
+
+ return 0;
+}
+
+static const struct drm_display_mode powkiddy_x55_mode = {
+ .hdisplay = 720,
+ .hsync_start = 720 + 44,
+ .hsync_end = 720 + 44 + 20,
+ .htotal = 720 + 44 + 20 + 20,
+ .vdisplay = 1280,
+ .vsync_start = 1280 + 12,
+ .vsync_end = 1280 + 12 + 10,
+ .vtotal = 1280 + 12 + 10 + 10,
+ .clock = 63290,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+ .width_mm = 67,
+ .height_mm = 121,
+};
+
+static const struct hx8394_panel_desc powkiddy_x55_desc = {
+ .mode = &powkiddy_x55_mode,
+ .lanes = 4,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET,
+ .format = MIPI_DSI_FMT_RGB888,
+ .init_sequence = powkiddy_x55_init_sequence,
+};
+
+static int gameforce_ace_init_sequence(struct hx8394 *ctx)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+ /* SETEXTC: Set extension command (B9h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETEXTC,
+ 0xff, 0x83, 0x99);
+
+ /* SETOFFSET (D2h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETOFFSET,
+ 0x77);
+
+ /* SETPOWER: Set power (B1h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETPOWER,
+ 0x02, 0x04, 0x74, 0x94, 0x01, 0x32, 0x33, 0x11, 0x11, 0xAB,
+ 0x4D, 0x56, 0x73, 0x02, 0x02);
+
+ /* SETDISP: Set display related register (B2h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETDISP,
+ 0x00, 0x80, 0x80, 0xAE, 0x05, 0x07, 0x5A, 0x11, 0x00, 0x00,
+ 0x10, 0x1E, 0x70, 0x03, 0xD4);
+
+ /* SETCYC: Set display waveform cycles (B4h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETCYC,
+ 0x00, 0xFF, 0x02, 0xC0, 0x02, 0xC0, 0x00, 0x00, 0x08, 0x00, 0x04,
+ 0x06, 0x00, 0x32, 0x04, 0x0A, 0x08, 0x21, 0x03, 0x01, 0x00, 0x0F,
+ 0xB8, 0x8B, 0x02, 0xC0, 0x02, 0xC0, 0x00, 0x00, 0x08, 0x00, 0x04,
+ 0x06, 0x00, 0x32, 0x04, 0x0A, 0x08, 0x01, 0x00, 0x0F, 0xB8, 0x01);
+
+ /* SETGIP0: Set GIP Option0 (D3h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x10, 0x04,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x05, 0x05, 0x07, 0x00, 0x00, 0x00, 0x05, 0x40);
+
+ /* Set GIP Option1 (D5h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP1,
+ 0x18, 0x18, 0x19, 0x19, 0x18, 0x18, 0x21, 0x20, 0x01, 0x00, 0x07,
+ 0x06, 0x05, 0x04, 0x03, 0x02, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x2F, 0x2F, 0x30, 0x30, 0x31, 0x31, 0x18, 0x18, 0x18, 0x18);
+
+ /* Set GIP Option2 (D6h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP2,
+ 0x18, 0x18, 0x19, 0x19, 0x40, 0x40, 0x20, 0x21, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x00, 0x01, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x2F, 0x2F, 0x30, 0x30, 0x31, 0x31, 0x40, 0x40, 0x40, 0x40);
+
+ /* Set GIP Option3 (D8h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP3,
+ 0xA2, 0xAA, 0x02, 0xA0, 0xA2, 0xA8, 0x02, 0xA0, 0xB0, 0x00, 0x00,
+ 0x00, 0xB0, 0x00, 0x00, 0x00);
+
+ /* Set register bank (BDh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETREGBANK,
+ 0x01);
+
+ /* Set GIP Option3 (D8h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP3,
+ 0xB0, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0xE2, 0xAA, 0x03,
+ 0xF0, 0xE2, 0xAA, 0x03, 0xF0);
+
+ /* Set register bank (BDh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETREGBANK,
+ 0x02);
+
+ /* Set GIP Option3 (D8h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGIP3,
+ 0xE2, 0xAA, 0x03, 0xF0, 0xE2, 0xAA, 0x03, 0xF);
+
+ /* Set register bank (BDh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETREGBANK,
+ 0x00);
+
+ /* SETVCOM: Set VCOM voltage (B6h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETVCOM,
+ 0x7A, 0x7A);
+
+ /* SETGAMMA: Set gamma curve related setting (E0h) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETGAMMA,
+ 0x00, 0x18, 0x27, 0x24, 0x5A, 0x68, 0x79, 0x78, 0x81, 0x8A, 0x92,
+ 0x99, 0x9E, 0xA7, 0xAF, 0xB4, 0xB9, 0xC3, 0xC7, 0xD1, 0xC6, 0xD4,
+ 0xD5, 0x6C, 0x67, 0x71, 0x77, 0x00, 0x00, 0x18, 0x27, 0x24, 0x5A,
+ 0x68, 0x79, 0x78, 0x81, 0x8A, 0x92, 0x99, 0x9E, 0xA7, 0xAF, 0xB4,
+ 0xB9, 0xC3, 0xC7, 0xD1, 0xC6, 0xD4, 0xD5, 0x6C, 0x67, 0x77);
+
+ /* Unknown command, C6h, not listed in the HX8399-c datasheet */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_UNKNOWN2,
+ 0xFF, 0xF9);
+
+ /* SETPANEL (CCh) */
+ mipi_dsi_dcs_write_seq(dsi, HX8394_CMD_SETPANEL,
+ 0x08);
+
+ return 0;
+}
+
+static const struct drm_display_mode gameforce_ace_mode = {
+ .hdisplay = 1080,
+ .hsync_start = 1080 + 32,
+ .hsync_end = 1080 + 32 + 8,
+ .htotal = 1080 + 32 + 8 + 32,
+ .vdisplay = 1920,
+ .vsync_start = 1920 + 16,
+ .vsync_end = 1920 + 16 + 2,
+ .vtotal = 1920 + 16 + 2 + 14,
+ .clock = 12400,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+ .width_mm = 68,
+ .height_mm = 120,
+};
+
+static const struct hx8394_panel_desc gameforce_ace_desc = {
+ .mode = &gameforce_ace_mode,
+ .lanes = 4,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET,
+ .format = MIPI_DSI_FMT_RGB888,
+ .init_sequence = gameforce_ace_init_sequence,
+};
+
+static int hx8394_enable(struct drm_panel *panel)
+{
+ struct hx8394 *ctx = panel_to_hx8394(panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+ int ret;
+
+ ret = ctx->desc->init_sequence(ctx);
+ if (ret) {
+ dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret) {
+ dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret);
+ return ret;
+ }
+
+ /* Panel is operational 120 msec after reset */
+ msleep(120);
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret) {
+ dev_err(ctx->dev, "Failed to turn on the display: %d\n", ret);
+ goto sleep_in;
+ }
+
+ return 0;
+
+sleep_in:
+ /* This will probably fail, but let's try orderly power off anyway. */
+ ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+ if (!ret)
+ msleep(50);
+
+ return ret;
+}
+
+static int hx8394_disable(struct drm_panel *panel)
+{
+ struct hx8394 *ctx = panel_to_hx8394(panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+ int ret;
+
+ ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+ if (ret) {
+ dev_err(ctx->dev, "Failed to enter sleep mode: %d\n", ret);
+ return ret;
+ }
+
+ msleep(50); /* about 3 frames */
+
+ return 0;
+}
+
+static int hx8394_unprepare(struct drm_panel *panel)
+{
+ struct hx8394 *ctx = panel_to_hx8394(panel);
+
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+
+ regulator_disable(ctx->iovcc);
+ regulator_disable(ctx->vcc);
+
+ return 0;
+}
+
+static int hx8394_prepare(struct drm_panel *panel)
+{
+ struct hx8394 *ctx = panel_to_hx8394(panel);
+ int ret;
+
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+
+ ret = regulator_enable(ctx->vcc);
+ if (ret) {
+ dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret);
+ return ret;
+ }
+
+ ret = regulator_enable(ctx->iovcc);
+ if (ret) {
+ dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret);
+ goto disable_vcc;
+ }
+
+ gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+
+ msleep(180);
+
+ return 0;
+
+disable_vcc:
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ regulator_disable(ctx->vcc);
+ return ret;
+}
+
+static int hx8394_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ struct hx8394 *ctx = panel_to_hx8394(panel);
+ struct drm_display_mode *mode;
+
+ connector->display_info.width_mm = mode->width_mm;
+ connector->display_info.height_mm = mode->height_mm;
+
+ mode = drm_mode_duplicate(connector->dev, ctx->desc->mode);
+ if (!mode) {
+ dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n",
+ ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
+ drm_mode_vrefresh(ctx->desc->mode));
+ return -ENOMEM;
+ }
+
+ drm_mode_set_name(mode);
+
+ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+
+ drm_mode_probed_add(connector, mode);
+
+ return 1;
+}
+
+static enum drm_panel_orientation hx8394_get_orientation(struct drm_panel *panel)
+{
+ struct hx8394 *ctx = panel_to_hx8394(panel);
+
+ return ctx->orientation;
+}
+
+static const struct drm_panel_funcs hx8394_drm_funcs = {
+ .disable = hx8394_disable,
+ .unprepare = hx8394_unprepare,
+ .prepare = hx8394_prepare,
+ .enable = hx8394_enable,
+ .get_modes = hx8394_get_modes,
+ .get_orientation = hx8394_get_orientation,
+};
+
+static int hx8394_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct hx8394 *ctx;
+ int ret;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(ctx->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
+ "Failed to get reset gpio\n");
+
+ ret = of_drm_get_panel_orientation(dev->of_node, &ctx->orientation);
+ if (ret < 0) {
+ dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, ret);
+ return ret;
+ }
+
+ mipi_dsi_set_drvdata(dsi, ctx);
+
+ ctx->dev = dev;
+ ctx->desc = of_device_get_match_data(dev);
+
+ dsi->mode_flags = ctx->desc->mode_flags;
+ dsi->format = ctx->desc->format;
+ dsi->lanes = ctx->desc->lanes;
+
+ ctx->vcc = devm_regulator_get(dev, "vcc");
+ if (IS_ERR(ctx->vcc))
+ return dev_err_probe(dev, PTR_ERR(ctx->vcc),
+ "Failed to request vcc regulator\n");
+
+ ctx->iovcc = devm_regulator_get(dev, "iovcc");
+ if (IS_ERR(ctx->iovcc))
+ return dev_err_probe(dev, PTR_ERR(ctx->iovcc),
+ "Failed to request iovcc regulator\n");
+
+ drm_panel_init(&ctx->panel, dev, &hx8394_drm_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+
+ ret = drm_panel_of_backlight(&ctx->panel);
+ if (ret)
+ return ret;
+
+ drm_panel_add(&ctx->panel);
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0) {
+ dev_err_probe(dev, ret, "mipi_dsi_attach failed\n");
+ drm_panel_remove(&ctx->panel);
+ return ret;
+ }
+
+ dev_dbg(dev, "%ux%u@%u %ubpp dsi %udl - ready\n",
+ ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
+ drm_mode_vrefresh(ctx->desc->mode),
+ mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes);
+
+ return 0;
+}
+
+static void hx8394_remove(struct mipi_dsi_device *dsi)
+{
+ struct hx8394 *ctx = mipi_dsi_get_drvdata(dsi);
+ int ret;
+
+ ret = mipi_dsi_detach(dsi);
+ if (ret < 0)
+ dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
+
+ drm_panel_remove(&ctx->panel);
+}
+
+static const struct of_device_id hx8394_of_match[] = {
+ { .compatible = "hannstar,hsd060bhw4", .data = &hsd060bhw4_desc },
+ { .compatible = "powkiddy,x55-panel", .data = &powkiddy_x55_desc },
+ { .compatible = "gameforce,ace-panel", .data = &gameforce_ace_desc },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, hx8394_of_match);
+
+static struct mipi_dsi_driver hx8394_driver = {
+ .probe = hx8394_probe,
+ .remove = hx8394_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .of_match_table = hx8394_of_match,
+ },
+};
+module_mipi_dsi_driver(hx8394_driver);
+
+MODULE_AUTHOR("Kamil Trzciński <ayufan@ayufan.eu>");
+MODULE_DESCRIPTION("DRM driver for Himax HX8394 based MIPI DSI panels");
+MODULE_LICENSE("GPL");

View file

@ -0,0 +1,141 @@
diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/lcd-hx8399c_mipi.dtsi linux/arch/arm64/boot/dts/rockchip/lcd-hx8399c_mipi.dtsi
--- linux.orig/arch/arm64/boot/dts/rockchip/lcd-hx8399c_mipi.dtsi 1970-01-01 00:00:00.000000000 +0000
+++ linux/arch/arm64/boot/dts/rockchip/lcd-hx8399c_mipi.dtsi 2024-03-06 16:58:28.748621788 +0000
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+&dsi0 {
+ status = "okay";
+ //rockchip,lane-rate = <1000>;
+ dsi0_panel: panel@0 {
+ status = "okay";
+ compatible = "simple-panel-dsi";
+ reg = <0>;
+ backlight = <&backlight>;
+ reset-delay-ms = <120>;
+ enable-delay-ms = <120>;
+ init-delay-ms = <120>;
+ stbyb-delay-ms = <120>;
+ prepare-delay-ms = <120>;
+ unprepare-delay-ms = <120>;
+ rotation = <90>;
+ disable-delay-ms = <120>;
+ dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;
+ dsi,format = <MIPI_DSI_FMT_RGB888>;
+ dsi,lanes = <4>;
+ //width-mm = <68>;
+ //height-mm = <120>;
+ panel-init-sequence = [
+ 39 00 04 B9 FF 83 99
+ 15 00 02 D2 77
+ 39 00 10 B1 02 04 74 94 01 32 33 11 11 AB 4D 56 73 02 02
+ 39 00 10 B2 00 80 80 AE 05 07 5A 11 00 00 10 1E 70 03 D4
+ 39 00 2d B4 00 FF 02 C0 02 C0 00 00 08 00 04 06 00 32 04 0A 08 21 03 01 00 0F B8 8B 02 C0 02 C0 00 00 08 00 04 06 00 32 04 0A 08 01 00 0F B8 01
+ 39 00 22 D3 00 00 00 00 00 00 06 00 00 10 04 00 04 00 00 00 00 00 00 00 00 00 00 01 00 05 05 07 00 00 00 05 40
+ 39 00 21 D5 18 18 19 19 18 18 21 20 01 00 07 06 05 04 03 02 18 18 18 18 18 18 2F 2F 30 30 31 31 18 18 18 18
+ 39 00 21 D6 18 18 19 19 40 40 20 21 02 03 04 05 06 07 00 01 40 40 40 40 40 40 2F 2F 30 30 31 31 40 40 40 40
+ 39 00 11 D8 A2 AA 02 A0 A2 A8 02 A0 B0 00 00 00 B0 00 00 00
+ 15 00 02 BD 01
+ 39 00 11 D8 B0 00 00 00 B0 00 00 00 E2 AA 03 F0 E2 AA 03 F0
+ 15 00 02 BD 02
+ 39 00 09 D8 E2 AA 03 F0 E2 AA 03 F0
+ 15 00 02 BD 00
+ 39 00 03 B6 7A 7A
+ 39 00 37 E0 00 18 27 24 5A 68 79 78 81 8A 92 99 9E A7 AF B4 B9 C3 C7 D1 C6 D4 D5 6C 67 71 77 00 00 18 27 24 5A 68 79 78 81 8A 92 99 9E A7 AF B4 B9 C3 C7 D1 C6 D4 D5 6C 67 77
+ 39 00 03 C6 FF F9
+ 15 00 02 CC 08
+ 05 78 01 11
+ 05 14 01 29
+ ];
+
+ panel-exit-sequence = [
+ 05 00 01 28
+ 05 00 01 10
+ ];
+
+ disp_timings0: display-timings {
+ native-mode = <&dsi0_timing0>;
+ dsi0_timing0: timing0 {
+ clock-frequency = <134920000>;
+ hactive = <1080>;
+ vactive = <1920>;
+ hfront-porch = <32>;
+ hsync-len = <8>;
+ hback-porch = <32>;
+ vfront-porch = <16>;
+ vsync-len = <2>;
+ vback-porch = <14>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <0>;
+ pixelclk-active = <1>;
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ panel_in_dsi: endpoint {
+ remote-endpoint = <&dsi_out_panel>;
+ };
+ };
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+ dsi_out_panel: endpoint {
+ remote-endpoint = <&panel_in_dsi>;
+ };
+ };
+ };
+
+};

View file

@ -1,217 +0,0 @@
diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3588s.dtsi linux/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
--- linux.orig/arch/arm64/boot/dts/rockchip/rk3588s.dtsi 2024-02-21 01:57:23.561577173 +0000
+++ linux/arch/arm64/boot/dts/rockchip/rk3588s.dtsi 2024-02-23 16:00:03.971337529 +0000
@@ -706,20 +706,20 @@
rockchip,high-temp-max-freq = <1608000>;
/* RK3588 cluster0 OPPs */
- opp-408000000 {
- opp-supported-hw = <0xf9 0xffff>;
- opp-hz = /bits/ 64 <408000000>;
- opp-microvolt = <675000 675000 950000>,
- <675000 675000 950000>;
- clock-latency-ns = <40000>;
- };
- opp-600000000 {
- opp-supported-hw = <0xf9 0xffff>;
- opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <675000 675000 950000>,
- <675000 675000 950000>;
- clock-latency-ns = <40000>;
- };
+ //opp-408000000 {
+ // opp-supported-hw = <0xf9 0xffff>;
+ // opp-hz = /bits/ 64 <408000000>;
+ // opp-microvolt = <675000 675000 950000>,
+ // <675000 675000 950000>;
+ // clock-latency-ns = <40000>;
+ //};
+ //opp-600000000 {
+ // opp-supported-hw = <0xf9 0xffff>;
+ // opp-hz = /bits/ 64 <600000000>;
+ // opp-microvolt = <675000 675000 950000>,
+ // <675000 675000 950000>;
+ // clock-latency-ns = <40000>;
+ //};
opp-816000000 {
opp-supported-hw = <0xf9 0xffff>;
opp-hz = /bits/ 64 <816000000>;
@@ -813,20 +813,20 @@
};
/* RK3588J/M cluster0 OPPs */
- opp-j-m-408000000 {
- opp-supported-hw = <0x06 0xffff>;
- opp-hz = /bits/ 64 <408000000>;
- opp-microvolt = <750000 750000 950000>,
- <750000 750000 950000>;
- clock-latency-ns = <40000>;
- };
- opp-j-m-600000000 {
- opp-supported-hw = <0x06 0xffff>;
- opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <750000 750000 950000>,
- <750000 750000 950000>;
- clock-latency-ns = <40000>;
- };
+ //opp-j-m-408000000 {
+ // opp-supported-hw = <0x06 0xffff>;
+ // opp-hz = /bits/ 64 <408000000>;
+ // opp-microvolt = <750000 750000 950000>,
+ // <750000 750000 950000>;
+ // clock-latency-ns = <40000>;
+ //};
+ //opp-j-m-600000000 {
+ // opp-supported-hw = <0x06 0xffff>;
+ // opp-hz = /bits/ 64 <600000000>;
+ // opp-microvolt = <750000 750000 950000>,
+ // <750000 750000 950000>;
+ // clock-latency-ns = <40000>;
+ //};
opp-j-m-816000000 {
opp-supported-hw = <0x06 0xffff>;
opp-hz = /bits/ 64 <816000000>;
@@ -971,21 +971,21 @@
rockchip,high-temp-max-freq = <2208000>;
/* RK3588 cluster1 OPPs */
- opp-408000000 {
- opp-supported-hw = <0xf9 0xffff>;
- opp-hz = /bits/ 64 <408000000>;
- opp-microvolt = <675000 675000 1000000>,
- <675000 675000 1000000>;
- clock-latency-ns = <40000>;
- opp-suspend;
- };
- opp-600000000 {
- opp-supported-hw = <0xf9 0xffff>;
- opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <675000 675000 1000000>,
- <675000 675000 1000000>;
- clock-latency-ns = <40000>;
- };
+ //opp-408000000 {
+ // opp-supported-hw = <0xf9 0xffff>;
+ // opp-hz = /bits/ 64 <408000000>;
+ // opp-microvolt = <675000 675000 1000000>,
+ // <675000 675000 1000000>;
+ // clock-latency-ns = <40000>;
+ // opp-suspend;
+ //};
+ //opp-600000000 {
+ // opp-supported-hw = <0xf9 0xffff>;
+ // opp-hz = /bits/ 64 <600000000>;
+ // opp-microvolt = <675000 675000 1000000>,
+ // <675000 675000 1000000>;
+ // clock-latency-ns = <40000>;
+ //};
opp-816000000 {
opp-supported-hw = <0xf9 0xffff>;
opp-hz = /bits/ 64 <816000000>;
@@ -1138,20 +1138,20 @@
};
/* RK3588J/M cluster1 OPPs */
- opp-j-m-408000000 {
- opp-supported-hw = <0x06 0xffff>;
- opp-hz = /bits/ 64 <408000000>;
- opp-microvolt = <750000 750000 950000>,
- <750000 750000 950000>;
- clock-latency-ns = <40000>;
- };
- opp-j-m-600000000 {
- opp-supported-hw = <0x06 0xffff>;
- opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <750000 750000 950000>,
- <750000 750000 950000>;
- clock-latency-ns = <40000>;
- };
+ //opp-j-m-408000000 {
+ // opp-supported-hw = <0x06 0xffff>;
+ // opp-hz = /bits/ 64 <408000000>;
+ // opp-microvolt = <750000 750000 950000>,
+ // <750000 750000 950000>;
+ // clock-latency-ns = <40000>;
+ //};
+ //opp-j-m-600000000 {
+ // opp-supported-hw = <0x06 0xffff>;
+ // opp-hz = /bits/ 64 <600000000>;
+ // opp-microvolt = <750000 750000 950000>,
+ // <750000 750000 950000>;
+ // clock-latency-ns = <40000>;
+ //};
opp-j-m-816000000 {
opp-supported-hw = <0x06 0xffff>;
opp-hz = /bits/ 64 <816000000>;
@@ -1304,21 +1304,21 @@
rockchip,high-temp-max-freq = <2208000>;
/* RK3588 cluster2 OPPs */
- opp-408000000 {
- opp-supported-hw = <0xf9 0x0ffff>;
- opp-hz = /bits/ 64 <408000000>;
- opp-microvolt = <675000 675000 1000000>,
- <675000 675000 1000000>;
- clock-latency-ns = <40000>;
- opp-suspend;
- };
- opp-600000000 {
- opp-supported-hw = <0xf9 0xffff>;
- opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <675000 675000 1000000>,
- <675000 675000 1000000>;
- clock-latency-ns = <40000>;
- };
+ //opp-408000000 {
+ // opp-supported-hw = <0xf9 0x0ffff>;
+ // opp-hz = /bits/ 64 <408000000>;
+ // opp-microvolt = <675000 675000 1000000>,
+ // <675000 675000 1000000>;
+ // clock-latency-ns = <40000>;
+ // opp-suspend;
+ //};
+ //opp-600000000 {
+ // opp-supported-hw = <0xf9 0xffff>;
+ // opp-hz = /bits/ 64 <600000000>;
+ // opp-microvolt = <675000 675000 1000000>,
+ // <675000 675000 1000000>;
+ // clock-latency-ns = <40000>;
+ //};
opp-816000000 {
opp-supported-hw = <0xf9 0xffff>;
opp-hz = /bits/ 64 <816000000>;
@@ -1467,20 +1467,20 @@
};
/* RK3588J/M cluster2 OPPs */
- opp-j-m-408000000 {
- opp-supported-hw = <0x06 0xffff>;
- opp-hz = /bits/ 64 <408000000>;
- opp-microvolt = <750000 750000 950000>,
- <750000 750000 950000>;
- clock-latency-ns = <40000>;
- };
- opp-j-m-600000000 {
- opp-supported-hw = <0x06 0xffff>;
- opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <750000 750000 950000>,
- <750000 750000 950000>;
- clock-latency-ns = <40000>;
- };
+ //opp-j-m-408000000 {
+ // opp-supported-hw = <0x06 0xffff>;
+ // opp-hz = /bits/ 64 <408000000>;
+ // opp-microvolt = <750000 750000 950000>,
+ // <750000 750000 950000>;
+ // clock-latency-ns = <40000>;
+ //};
+ //opp-j-m-600000000 {
+ // opp-supported-hw = <0x06 0xffff>;
+ // opp-hz = /bits/ 64 <600000000>;
+ // opp-microvolt = <750000 750000 950000>,
+ // <750000 750000 950000>;
+ // clock-latency-ns = <40000>;
+ //};
opp-j-m-816000000 {
opp-supported-hw = <0x06 0xffff>;
opp-hz = /bits/ 64 <816000000>;

View file

@ -1,691 +0,0 @@
diff -rupN linux.orig/Makefile linux/Makefile
--- linux.orig/Makefile 2024-02-21 01:57:23.445573377 +0000
+++ linux/Makefile 2024-02-22 16:21:29.661040043 +0000
@@ -1075,7 +1075,7 @@ endif
KBUILD_CFLAGS += -Werror=date-time
# enforce correct pointer usage
-KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)
+#KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)
# Require designated initializers for all marked structures
KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
diff -rupN linux.orig/drivers/iio/adc/ti-ads1015.c linux/drivers/iio/adc/ti-ads1015.c
--- linux.orig/drivers/iio/adc/ti-ads1015.c 2024-02-21 01:57:24.113595238 +0000
+++ linux/drivers/iio/adc/ti-ads1015.c 2024-02-22 16:18:15.319056297 +0000
@@ -76,15 +76,10 @@
#define ADS1015_DEFAULT_DATA_RATE 4
#define ADS1015_DEFAULT_CHAN 0
-struct ads1015_chip_data {
- struct iio_chan_spec const *channels;
- int num_channels;
- const struct iio_info *info;
- const int *data_rate;
- const int data_rate_len;
- const int *scale;
- const int scale_len;
- bool has_comparator;
+enum chip_ids {
+ ADSXXXX = 0,
+ ADS1015,
+ ADS1115,
};
enum ads1015_channels {
@@ -99,11 +94,11 @@ enum ads1015_channels {
ADS1015_TIMESTAMP,
};
-static const int ads1015_data_rate[] = {
+static const unsigned int ads1015_data_rate[] = {
128, 250, 490, 920, 1600, 2400, 3300, 3300
};
-static const int ads1115_data_rate[] = {
+static const unsigned int ads1115_data_rate[] = {
8, 16, 32, 64, 128, 250, 475, 860
};
@@ -111,28 +106,10 @@ static const int ads1115_data_rate[] = {
* Translation from PGA bits to full-scale positive and negative input voltage
* range in mV
*/
-static const int ads1015_fullscale_range[] = {
+static int ads1015_fullscale_range[] = {
6144, 4096, 2048, 1024, 512, 256, 256, 256
};
-static const int ads1015_scale[] = { /* 12bit ADC */
- 256, 11,
- 512, 11,
- 1024, 11,
- 2048, 11,
- 4096, 11,
- 6144, 11
-};
-
-static const int ads1115_scale[] = { /* 16bit ADC */
- 256, 15,
- 512, 15,
- 1024, 15,
- 2048, 15,
- 4096, 15,
- 6144, 15
-};
-
/*
* Translation from COMP_QUE field value to the number of successive readings
* exceed the threshold values before an interrupt is generated
@@ -157,53 +134,71 @@ static const struct iio_event_spec ads10
},
};
-/*
- * Compile-time check whether _fitbits can accommodate up to _testbits
- * bits. Returns _fitbits on success, fails to compile otherwise.
- *
- * The test works such that it multiplies constant _fitbits by constant
- * double-negation of size of a non-empty structure, i.e. it multiplies
- * constant _fitbits by constant 1 in each successful compilation case.
- * The non-empty structure may contain C11 _Static_assert(), make use of
- * this and place the kernel variant of static assert in there, so that
- * it performs the compile-time check for _testbits <= _fitbits. Note
- * that it is not possible to directly use static_assert in compound
- * statements, hence this convoluted construct.
- */
-#define FIT_CHECK(_testbits, _fitbits) \
- ( \
- (_fitbits) * \
- !!sizeof(struct { \
- static_assert((_testbits) <= (_fitbits)); \
- int pad; \
- }) \
- )
+#define ADS1015_V_CHAN(_chan, _addr) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .address = _addr, \
+ .channel = _chan, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_index = _addr, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 12, \
+ .storagebits = 16, \
+ .shift = 4, \
+ .endianness = IIO_CPU, \
+ }, \
+ .event_spec = ads1015_events, \
+ .num_event_specs = ARRAY_SIZE(ads1015_events), \
+ .datasheet_name = "AIN"#_chan, \
+}
-#define ADS1015_V_CHAN(_chan, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \
+#define ADS1015_V_DIFF_CHAN(_chan, _chan2, _addr) { \
.type = IIO_VOLTAGE, \
+ .differential = 1, \
.indexed = 1, \
.address = _addr, \
.channel = _chan, \
+ .channel2 = _chan2, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
- .info_mask_shared_by_all_available = \
+ .scan_index = _addr, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 12, \
+ .storagebits = 16, \
+ .shift = 4, \
+ .endianness = IIO_CPU, \
+ }, \
+ .event_spec = ads1015_events, \
+ .num_event_specs = ARRAY_SIZE(ads1015_events), \
+ .datasheet_name = "AIN"#_chan"-AIN"#_chan2, \
+}
+
+#define ADS1115_V_CHAN(_chan, _addr) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .address = _addr, \
+ .channel = _chan, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.scan_index = _addr, \
.scan_type = { \
.sign = 's', \
- .realbits = (_realbits), \
- .storagebits = FIT_CHECK((_realbits) + (_shift), 16), \
- .shift = (_shift), \
+ .realbits = 16, \
+ .storagebits = 16, \
.endianness = IIO_CPU, \
}, \
- .event_spec = (_event_spec), \
- .num_event_specs = (_num_event_specs), \
+ .event_spec = ads1015_events, \
+ .num_event_specs = ARRAY_SIZE(ads1015_events), \
.datasheet_name = "AIN"#_chan, \
}
-#define ADS1015_V_DIFF_CHAN(_chan, _chan2, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \
+#define ADS1115_V_DIFF_CHAN(_chan, _chan2, _addr) { \
.type = IIO_VOLTAGE, \
.differential = 1, \
.indexed = 1, \
@@ -213,19 +208,15 @@ static const struct iio_event_spec ads10
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
- .info_mask_shared_by_all_available = \
- BIT(IIO_CHAN_INFO_SCALE) | \
- BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.scan_index = _addr, \
.scan_type = { \
.sign = 's', \
- .realbits = (_realbits), \
- .storagebits = FIT_CHECK((_realbits) + (_shift), 16), \
- .shift = (_shift), \
+ .realbits = 16, \
+ .storagebits = 16, \
.endianness = IIO_CPU, \
}, \
- .event_spec = (_event_spec), \
- .num_event_specs = (_num_event_specs), \
+ .event_spec = ads1015_events, \
+ .num_event_specs = ARRAY_SIZE(ads1015_events), \
.datasheet_name = "AIN"#_chan"-AIN"#_chan2, \
}
@@ -254,7 +245,7 @@ struct ads1015_data {
unsigned int comp_mode;
struct ads1015_thresh_data thresh_data[ADS1015_CHANNELS];
- const struct ads1015_chip_data *chip;
+ unsigned int *data_rate;
/*
* Set to true when the ADC is switched to the continuous-conversion
* mode and exits from a power-down state. This flag is used to avoid
@@ -282,91 +273,49 @@ static void ads1015_event_channel_disabl
data->event_channel = ADS1015_CHANNELS;
}
-static const struct regmap_range ads1015_writeable_ranges[] = {
- regmap_reg_range(ADS1015_CFG_REG, ADS1015_HI_THRESH_REG),
-};
-
-static const struct regmap_access_table ads1015_writeable_table = {
- .yes_ranges = ads1015_writeable_ranges,
- .n_yes_ranges = ARRAY_SIZE(ads1015_writeable_ranges),
-};
+static bool ads1015_is_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case ADS1015_CFG_REG:
+ case ADS1015_LO_THRESH_REG:
+ case ADS1015_HI_THRESH_REG:
+ return true;
+ default:
+ return false;
+ }
+}
static const struct regmap_config ads1015_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
.max_register = ADS1015_HI_THRESH_REG,
- .wr_table = &ads1015_writeable_table,
-};
-
-static const struct regmap_range tla2024_writeable_ranges[] = {
- regmap_reg_range(ADS1015_CFG_REG, ADS1015_CFG_REG),
-};
-
-static const struct regmap_access_table tla2024_writeable_table = {
- .yes_ranges = tla2024_writeable_ranges,
- .n_yes_ranges = ARRAY_SIZE(tla2024_writeable_ranges),
-};
-
-static const struct regmap_config tla2024_regmap_config = {
- .reg_bits = 8,
- .val_bits = 16,
- .max_register = ADS1015_CFG_REG,
- .wr_table = &tla2024_writeable_table,
+ .writeable_reg = ads1015_is_writeable_reg,
};
static const struct iio_chan_spec ads1015_channels[] = {
- ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 12, 4,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 12, 4,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 12, 4,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 12, 4,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_CHAN(0, ADS1015_AIN0, 12, 4,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_CHAN(1, ADS1015_AIN1, 12, 4,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_CHAN(2, ADS1015_AIN2, 12, 4,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_CHAN(3, ADS1015_AIN3, 12, 4,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
+ ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1),
+ ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3),
+ ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3),
+ ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3),
+ ADS1015_V_CHAN(0, ADS1015_AIN0),
+ ADS1015_V_CHAN(1, ADS1015_AIN1),
+ ADS1015_V_CHAN(2, ADS1015_AIN2),
+ ADS1015_V_CHAN(3, ADS1015_AIN3),
IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP),
};
static const struct iio_chan_spec ads1115_channels[] = {
- ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 16, 0,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 16, 0,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 16, 0,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 16, 0,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_CHAN(0, ADS1015_AIN0, 16, 0,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_CHAN(1, ADS1015_AIN1, 16, 0,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_CHAN(2, ADS1015_AIN2, 16, 0,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
- ADS1015_V_CHAN(3, ADS1015_AIN3, 16, 0,
- ads1015_events, ARRAY_SIZE(ads1015_events)),
+ ADS1115_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1),
+ ADS1115_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3),
+ ADS1115_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3),
+ ADS1115_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3),
+ ADS1115_V_CHAN(0, ADS1015_AIN0),
+ ADS1115_V_CHAN(1, ADS1015_AIN1),
+ ADS1115_V_CHAN(2, ADS1015_AIN2),
+ ADS1115_V_CHAN(3, ADS1015_AIN3),
IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP),
};
-static const struct iio_chan_spec tla2024_channels[] = {
- ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 12, 4, NULL, 0),
- ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 12, 4, NULL, 0),
- ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 12, 4, NULL, 0),
- ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 12, 4, NULL, 0),
- ADS1015_V_CHAN(0, ADS1015_AIN0, 12, 4, NULL, 0),
- ADS1015_V_CHAN(1, ADS1015_AIN1, 12, 4, NULL, 0),
- ADS1015_V_CHAN(2, ADS1015_AIN2, 12, 4, NULL, 0),
- ADS1015_V_CHAN(3, ADS1015_AIN3, 12, 4, NULL, 0),
- IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP),
-};
-
-
#ifdef CONFIG_PM
static int ads1015_set_power_state(struct ads1015_data *data, bool on)
{
@@ -374,7 +323,9 @@ static int ads1015_set_power_state(struc
struct device *dev = regmap_get_device(data->regmap);
if (on) {
- ret = pm_runtime_resume_and_get(dev);
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ pm_runtime_put_noidle(dev);
} else {
pm_runtime_mark_last_busy(dev);
ret = pm_runtime_put_autosuspend(dev);
@@ -395,7 +346,6 @@ static int ads1015_set_power_state(struc
static
int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val)
{
- const int *data_rate = data->chip->data_rate;
int ret, pga, dr, dr_old, conv_time;
unsigned int old, mask, cfg;
@@ -430,8 +380,8 @@ int ads1015_get_adc_result(struct ads101
}
if (data->conv_invalid) {
dr_old = (old & ADS1015_CFG_DR_MASK) >> ADS1015_CFG_DR_SHIFT;
- conv_time = DIV_ROUND_UP(USEC_PER_SEC, data_rate[dr_old]);
- conv_time += DIV_ROUND_UP(USEC_PER_SEC, data_rate[dr]);
+ conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr_old]);
+ conv_time += DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]);
conv_time += conv_time / 10; /* 10% internal clock inaccuracy */
usleep_range(conv_time, conv_time + 1);
data->conv_invalid = false;
@@ -497,8 +447,8 @@ static int ads1015_set_data_rate(struct
{
int i;
- for (i = 0; i < data->chip->data_rate_len; i++) {
- if (data->chip->data_rate[i] == rate) {
+ for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++) {
+ if (data->data_rate[i] == rate) {
data->channel_data[chan].data_rate = i;
return 0;
}
@@ -507,32 +457,6 @@ static int ads1015_set_data_rate(struct
return -EINVAL;
}
-static int ads1015_read_avail(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- const int **vals, int *type, int *length,
- long mask)
-{
- struct ads1015_data *data = iio_priv(indio_dev);
-
- if (chan->type != IIO_VOLTAGE)
- return -EINVAL;
-
- switch (mask) {
- case IIO_CHAN_INFO_SCALE:
- *type = IIO_VAL_FRACTIONAL_LOG2;
- *vals = data->chip->scale;
- *length = data->chip->scale_len;
- return IIO_AVAIL_LIST;
- case IIO_CHAN_INFO_SAMP_FREQ:
- *type = IIO_VAL_INT;
- *vals = data->chip->data_rate;
- *length = data->chip->data_rate_len;
- return IIO_AVAIL_LIST;
- default:
- return -EINVAL;
- }
-}
-
static int ads1015_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
@@ -542,7 +466,9 @@ static int ads1015_read_raw(struct iio_d
mutex_lock(&data->lock);
switch (mask) {
- case IIO_CHAN_INFO_RAW:
+ case IIO_CHAN_INFO_RAW: {
+ int shift = chan->scan_type.shift;
+
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
break;
@@ -563,8 +489,7 @@ static int ads1015_read_raw(struct iio_d
goto release_direct;
}
- *val = sign_extend32(*val >> chan->scan_type.shift,
- chan->scan_type.realbits - 1);
+ *val = sign_extend32(*val >> shift, 15 - shift);
ret = ads1015_set_power_state(data, false);
if (ret < 0)
@@ -574,6 +499,7 @@ static int ads1015_read_raw(struct iio_d
release_direct:
iio_device_release_direct_mode(indio_dev);
break;
+ }
case IIO_CHAN_INFO_SCALE:
idx = data->channel_data[chan->address].pga;
*val = ads1015_fullscale_range[idx];
@@ -582,7 +508,7 @@ release_direct:
break;
case IIO_CHAN_INFO_SAMP_FREQ:
idx = data->channel_data[chan->address].data_rate;
- *val = data->chip->data_rate[idx];
+ *val = data->data_rate[idx];
ret = IIO_VAL_INT;
break;
default:
@@ -642,7 +568,7 @@ static int ads1015_read_event(struct iio
dr = data->channel_data[chan->address].data_rate;
comp_queue = data->thresh_data[chan->address].comp_queue;
period = ads1015_comp_queue[comp_queue] *
- USEC_PER_SEC / data->chip->data_rate[dr];
+ USEC_PER_SEC / data->data_rate[dr];
*val = period / USEC_PER_SEC;
*val2 = period % USEC_PER_SEC;
@@ -664,7 +590,6 @@ static int ads1015_write_event(struct ii
int val2)
{
struct ads1015_data *data = iio_priv(indio_dev);
- const int *data_rate = data->chip->data_rate;
int realbits = chan->scan_type.realbits;
int ret = 0;
long long period;
@@ -690,7 +615,7 @@ static int ads1015_write_event(struct ii
for (i = 0; i < ARRAY_SIZE(ads1015_comp_queue) - 1; i++) {
if (period <= ads1015_comp_queue[i] *
- USEC_PER_SEC / data_rate[dr])
+ USEC_PER_SEC / data->data_rate[dr])
break;
}
data->thresh_data[chan->address].comp_queue = i;
@@ -881,20 +806,54 @@ static const struct iio_buffer_setup_ops
.validate_scan_mask = &iio_validate_scan_mask_onehot,
};
+static IIO_CONST_ATTR_NAMED(ads1015_scale_available, scale_available,
+ "3 2 1 0.5 0.25 0.125");
+static IIO_CONST_ATTR_NAMED(ads1115_scale_available, scale_available,
+ "0.1875 0.125 0.0625 0.03125 0.015625 0.007813");
+
+static IIO_CONST_ATTR_NAMED(ads1015_sampling_frequency_available,
+ sampling_frequency_available, "128 250 490 920 1600 2400 3300");
+static IIO_CONST_ATTR_NAMED(ads1115_sampling_frequency_available,
+ sampling_frequency_available, "8 16 32 64 128 250 475 860");
+
+static struct attribute *ads1015_attributes[] = {
+ &iio_const_attr_ads1015_scale_available.dev_attr.attr,
+ &iio_const_attr_ads1015_sampling_frequency_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group ads1015_attribute_group = {
+ .attrs = ads1015_attributes,
+};
+
+static struct attribute *ads1115_attributes[] = {
+ &iio_const_attr_ads1115_scale_available.dev_attr.attr,
+ &iio_const_attr_ads1115_sampling_frequency_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group ads1115_attribute_group = {
+ .attrs = ads1115_attributes,
+};
+
static const struct iio_info ads1015_info = {
- .read_avail = ads1015_read_avail,
.read_raw = ads1015_read_raw,
.write_raw = ads1015_write_raw,
.read_event_value = ads1015_read_event,
.write_event_value = ads1015_write_event,
.read_event_config = ads1015_read_event_config,
.write_event_config = ads1015_write_event_config,
+ .attrs = &ads1015_attribute_group,
};
-static const struct iio_info tla2024_info = {
- .read_avail = ads1015_read_avail,
+static const struct iio_info ads1115_info = {
.read_raw = ads1015_read_raw,
.write_raw = ads1015_write_raw,
+ .read_event_value = ads1015_read_event,
+ .write_event_value = ads1015_write_event,
+ .read_event_config = ads1015_read_event_config,
+ .write_event_config = ads1015_write_event_config,
+ .attrs = &ads1115_attribute_group,
};
static int ads1015_client_get_channels_config(struct i2c_client *client)
@@ -977,18 +936,12 @@ static int ads1015_set_conv_mode(struct
static int ads1015_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- const struct ads1015_chip_data *chip;
struct iio_dev *indio_dev;
struct ads1015_data *data;
int ret;
+ enum chip_ids chip;
int i;
- chip = device_get_match_data(&client->dev);
- if (!chip)
- chip = (const struct ads1015_chip_data *)id->driver_data;
- if (!chip)
- return dev_err_probe(&client->dev, -EINVAL, "Unknown chip\n");
-
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
@@ -1001,12 +954,28 @@ static int ads1015_probe(struct i2c_clie
indio_dev->name = ADS1015_DRV_NAME;
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = chip->channels;
- indio_dev->num_channels = chip->num_channels;
- indio_dev->info = chip->info;
- data->chip = chip;
- data->event_channel = ADS1015_CHANNELS;
+ chip = (enum chip_ids)device_get_match_data(&client->dev);
+ if (chip == ADSXXXX)
+ chip = id->driver_data;
+ switch (chip) {
+ case ADS1015:
+ indio_dev->channels = ads1015_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ads1015_channels);
+ indio_dev->info = &ads1015_info;
+ data->data_rate = (unsigned int *) &ads1015_data_rate;
+ break;
+ case ADS1115:
+ indio_dev->channels = ads1115_channels;
+ indio_dev->num_channels = ARRAY_SIZE(ads1115_channels);
+ indio_dev->info = &ads1115_info;
+ data->data_rate = (unsigned int *) &ads1115_data_rate;
+ break;
+ default:
+ dev_err(&client->dev, "Unknown chip %d\n", chip);
+ return -EINVAL;
+ }
+ data->event_channel = ADS1015_CHANNELS;
/*
* Set default lower and upper threshold to min and max value
* respectively.
@@ -1021,9 +990,7 @@ static int ads1015_probe(struct i2c_clie
/* we need to keep this ABI the same as used by hwmon ADS1015 driver */
ads1015_get_channels_config(client);
- data->regmap = devm_regmap_init_i2c(client, chip->has_comparator ?
- &ads1015_regmap_config :
- &tla2024_regmap_config);
+ data->regmap = devm_regmap_init_i2c(client, &ads1015_regmap_config);
if (IS_ERR(data->regmap)) {
dev_err(&client->dev, "Failed to allocate register map\n");
return PTR_ERR(data->regmap);
@@ -1037,7 +1004,7 @@ static int ads1015_probe(struct i2c_clie
return ret;
}
- if (client->irq && chip->has_comparator) {
+ if (client->irq) {
unsigned long irq_trig =
irqd_get_trigger_type(irq_get_irq_data(client->irq));
unsigned int cfg_comp_mask = ADS1015_CFG_COMP_QUE_MASK |
@@ -1094,22 +1061,19 @@ static int ads1015_probe(struct i2c_clie
return 0;
}
-static void ads1015_remove(struct i2c_client *client)
+static int ads1015_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ads1015_data *data = iio_priv(indio_dev);
- int ret;
iio_device_unregister(indio_dev);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
/* power down single shot mode */
- ret = ads1015_set_conv_mode(data, ADS1015_SINGLESHOT);
- if (ret)
- dev_warn(&client->dev, "Failed to power down (%pe)\n",
- ERR_PTR(ret));
+ return ads1015_set_conv_mode(data, ADS1015_SINGLESHOT);
}
#ifdef CONFIG_PM
@@ -1140,51 +1104,22 @@ static const struct dev_pm_ops ads1015_p
ads1015_runtime_resume, NULL)
};
-static const struct ads1015_chip_data ads1015_data = {
- .channels = ads1015_channels,
- .num_channels = ARRAY_SIZE(ads1015_channels),
- .info = &ads1015_info,
- .data_rate = ads1015_data_rate,
- .data_rate_len = ARRAY_SIZE(ads1015_data_rate),
- .scale = ads1015_scale,
- .scale_len = ARRAY_SIZE(ads1015_scale),
- .has_comparator = true,
-};
-
-static const struct ads1015_chip_data ads1115_data = {
- .channels = ads1115_channels,
- .num_channels = ARRAY_SIZE(ads1115_channels),
- .info = &ads1015_info,
- .data_rate = ads1115_data_rate,
- .data_rate_len = ARRAY_SIZE(ads1115_data_rate),
- .scale = ads1115_scale,
- .scale_len = ARRAY_SIZE(ads1115_scale),
- .has_comparator = true,
-};
-
-static const struct ads1015_chip_data tla2024_data = {
- .channels = tla2024_channels,
- .num_channels = ARRAY_SIZE(tla2024_channels),
- .info = &tla2024_info,
- .data_rate = ads1015_data_rate,
- .data_rate_len = ARRAY_SIZE(ads1015_data_rate),
- .scale = ads1015_scale,
- .scale_len = ARRAY_SIZE(ads1015_scale),
- .has_comparator = false,
-};
-
static const struct i2c_device_id ads1015_id[] = {
- { "ads1015", (kernel_ulong_t)&ads1015_data },
- { "ads1115", (kernel_ulong_t)&ads1115_data },
- { "tla2024", (kernel_ulong_t)&tla2024_data },
+ {"ads1015", ADS1015},
+ {"ads1115", ADS1115},
{}
};
MODULE_DEVICE_TABLE(i2c, ads1015_id);
static const struct of_device_id ads1015_of_match[] = {
- { .compatible = "ti,ads1015", .data = &ads1015_data },
- { .compatible = "ti,ads1115", .data = &ads1115_data },
- { .compatible = "ti,tla2024", .data = &tla2024_data },
+ {
+ .compatible = "ti,ads1015",
+ .data = (void *)ADS1015
+ },
+ {
+ .compatible = "ti,ads1115",
+ .data = (void *)ADS1115
+ },
{}
};
MODULE_DEVICE_TABLE(of, ads1015_of_match);

View file

@ -0,0 +1,68 @@
diff -rupN linux.orig/arch/arm64/boot/dts/rockchip/rk3588s.dtsi linux/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
--- linux.orig/arch/arm64/boot/dts/rockchip/rk3588s.dtsi 2024-03-07 02:13:27.416651707 +0000
+++ linux/arch/arm64/boot/dts/rockchip/rk3588s.dtsi 2024-03-07 02:18:35.049791618 +0000
@@ -706,20 +706,6 @@
rockchip,high-temp-max-freq = <1608000>;
/* RK3588 cluster0 OPPs */
- opp-408000000 {
- opp-supported-hw = <0xf9 0xffff>;
- opp-hz = /bits/ 64 <408000000>;
- opp-microvolt = <675000 675000 950000>,
- <675000 675000 950000>;
- clock-latency-ns = <40000>;
- };
- opp-600000000 {
- opp-supported-hw = <0xf9 0xffff>;
- opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <675000 675000 950000>,
- <675000 675000 950000>;
- clock-latency-ns = <40000>;
- };
opp-816000000 {
opp-supported-hw = <0xf9 0xffff>;
opp-hz = /bits/ 64 <816000000>;
@@ -971,21 +957,6 @@
rockchip,high-temp-max-freq = <2208000>;
/* RK3588 cluster1 OPPs */
- opp-408000000 {
- opp-supported-hw = <0xf9 0xffff>;
- opp-hz = /bits/ 64 <408000000>;
- opp-microvolt = <675000 675000 1000000>,
- <675000 675000 1000000>;
- clock-latency-ns = <40000>;
- opp-suspend;
- };
- opp-600000000 {
- opp-supported-hw = <0xf9 0xffff>;
- opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <675000 675000 1000000>,
- <675000 675000 1000000>;
- clock-latency-ns = <40000>;
- };
opp-816000000 {
opp-supported-hw = <0xf9 0xffff>;
opp-hz = /bits/ 64 <816000000>;
@@ -1304,21 +1275,6 @@
rockchip,high-temp-max-freq = <2208000>;
/* RK3588 cluster2 OPPs */
- opp-408000000 {
- opp-supported-hw = <0xf9 0x0ffff>;
- opp-hz = /bits/ 64 <408000000>;
- opp-microvolt = <675000 675000 1000000>,
- <675000 675000 1000000>;
- clock-latency-ns = <40000>;
- opp-suspend;
- };
- opp-600000000 {
- opp-supported-hw = <0xf9 0xffff>;
- opp-hz = /bits/ 64 <600000000>;
- opp-microvolt = <675000 675000 1000000>,
- <675000 675000 1000000>;
- clock-latency-ns = <40000>;
- };
opp-816000000 {
opp-supported-hw = <0xf9 0xffff>;
opp-hz = /bits/ 64 <816000000>;

View file

@ -1,6 +1,6 @@
diff -rupN linux.orig/sound/soc/codecs/es8323.c linux/sound/soc/codecs/es8323.c
--- linux.orig/sound/soc/codecs/es8323.c 2024-02-22 23:16:12.484295695 +0000
+++ linux/sound/soc/codecs/es8323.c 2024-02-22 23:23:57.934593039 +0000
--- linux.orig/sound/soc/codecs/es8323.c 2024-03-06 21:56:51.358228509 +0000
+++ linux/sound/soc/codecs/es8323.c 2024-03-06 21:58:44.317922609 +0000
@@ -25,6 +25,11 @@
#include <sound/soc-dapm.h>
#include <sound/initval.h>
@ -60,7 +60,7 @@ diff -rupN linux.orig/sound/soc/codecs/es8323.c linux/sound/soc/codecs/es8323.c
static int es8323_mute(struct snd_soc_dai *dai, int mute, int stream)
-{
- return 0;
+{
+{
+ // struct snd_soc_component *component = dai->component;
+ // struct es8323_priv *es8323 = snd_soc_component_get_drvdata(component);
+
@ -73,7 +73,7 @@ diff -rupN linux.orig/sound/soc/codecs/es8323.c linux/sound/soc/codecs/es8323.c
+
+ if (hp) {
+ // printk("gsy es8323_mute\n");
+ // gsy add
+ // gsy add
+ if (mute) {
+ gpio_direction_output(133, 0);// spk ctl
+ gpio_set_value(133, 0);
@ -130,25 +130,13 @@ diff -rupN linux.orig/sound/soc/codecs/es8323.c linux/sound/soc/codecs/es8323.c
+ GPIOD_OUT_LOW);
+ if (IS_ERR(es8323->spk_ctl_gpio))
+ return PTR_ERR(es8323->spk_ctl_gpio);
+
+
es8323->mclk = devm_clk_get(component->dev, "mclk");
if (IS_ERR(es8323->mclk)) {
dev_err(component->dev, "%s mclk is missing or invalid\n", __func__);
@@ -870,9 +918,10 @@ static int es8323_i2c_probe(struct i2c_c
return ret;
}
-static void es8323_i2c_remove(struct i2c_client *client)
+static int es8323_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_component(&client->dev);
+ return 0;
}
static const struct i2c_device_id es8323_i2c_id[] = {
diff -rupN linux.orig/sound/soc/codecs/es8323.h linux/sound/soc/codecs/es8323.h
--- linux.orig/sound/soc/codecs/es8323.h 2024-02-22 23:16:12.484295695 +0000
+++ linux/sound/soc/codecs/es8323.h 2024-02-22 23:17:51.183289828 +0000
--- linux.orig/sound/soc/codecs/es8323.h 2024-03-06 21:56:51.362228640 +0000
+++ linux/sound/soc/codecs/es8323.h 2024-03-06 22:01:36.203539209 +0000
@@ -80,7 +80,7 @@
#define ES8323_ADC_MUTE ES8323_ADCCONTROL7
@ -159,9 +147,9 @@ diff -rupN linux.orig/sound/soc/codecs/es8323.h linux/sound/soc/codecs/es8323.h
#define ES8323_IFACE ES8323_MASTERMODE
diff -rupN linux.orig/sound/soc/rockchip/rockchip_multicodecs.c linux/sound/soc/rockchip/rockchip_multicodecs.c
--- linux.orig/sound/soc/rockchip/rockchip_multicodecs.c 2024-02-22 23:16:12.580298595 +0000
+++ linux/sound/soc/rockchip/rockchip_multicodecs.c 2024-02-22 23:20:46.900676454 +0000
@@ -272,9 +272,13 @@ static int mc_hp_event(struct snd_soc_da
--- linux.orig/sound/soc/rockchip/rockchip_multicodecs.c 2024-03-06 21:56:51.478232435 +0000
+++ linux/sound/soc/rockchip/rockchip_multicodecs.c 2024-03-06 22:04:55.818056848 +0000
@@ -293,8 +293,11 @@ static int mc_spk_event(struct snd_soc_d
struct snd_soc_card *card = w->dapm->card;
struct multicodecs_data *mc_data = snd_soc_card_get_drvdata(card);
@ -169,10 +157,7 @@ diff -rupN linux.orig/sound/soc/rockchip/rockchip_multicodecs.c linux/sound/soc/
+
switch (event) {
case SND_SOC_DAPM_POST_PMU:
- gpiod_set_value_cansleep(mc_data->hp_ctl_gpio, 1);
+ //gpiod_set_value_cansleep(mc_data->hp_ctl_gpio, 1);
+ if (!(jack_headset->status & SND_JACK_HEADPHONE))
+ gpiod_set_value_cansleep(mc_data->spk_ctl_gpio, 1);
gpiod_set_value_cansleep(mc_data->spk_ctl_gpio, 1);
break;
case SND_SOC_DAPM_PRE_PMD:
gpiod_set_value_cansleep(mc_data->hp_ctl_gpio, 0);

View file

@ -1,23 +0,0 @@
From 9e1e2c5cc83eff4339b34fb600e88a39563aba93 Mon Sep 17 00:00:00 2001
From: Joshua Riek <jjriek@verizon.net>
Date: Fri, 1 Mar 2024 08:34:05 -0500
Subject: [PATCH] drm: set DRM_RENDER_ALLOW flag on DRM_IOCTL_MODE_DESTROY_DUMB
ioctl
---
drivers/gpu/drm/drm_ioctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 0dc0d2de8857..4b839f17f315 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -682,7 +682,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, 0),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, 0),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER),

View file

@ -0,0 +1,29 @@
diff -rupN linux.orig/drivers/clk/rockchip/clk-rk3588.c linux/drivers/clk/rockchip/clk-rk3588.c
--- linux.orig/drivers/clk/rockchip/clk-rk3588.c 2024-03-06 22:11:33.951046369 +0000
+++ linux/drivers/clk/rockchip/clk-rk3588.c 2024-03-07 00:00:30.202206013 +0000
@@ -2065,13 +2065,13 @@ static struct rockchip_clk_branch rk3588
RK3588_CLKGATE_CON(72), 4, GFLAGS),
GATE(HCLK_VOP, "hclk_vop", "hclk_vop_root", 0,
RK3588_CLKGATE_CON(52), 8, GFLAGS),
- COMPOSITE(DCLK_VOP0_SRC, "dclk_vop0_src", gpll_cpll_v0pll_aupll_p, 0,
+ COMPOSITE(DCLK_VOP0_SRC, "dclk_vop0_src", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_NO_REPARENT,
RK3588_CLKSEL_CON(111), 7, 2, MFLAGS, 0, 7, DFLAGS,
RK3588_CLKGATE_CON(52), 10, GFLAGS),
- COMPOSITE(DCLK_VOP1_SRC, "dclk_vop1_src", gpll_cpll_v0pll_aupll_p, 0,
+ COMPOSITE(DCLK_VOP1_SRC, "dclk_vop1_src", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_NO_REPARENT,
RK3588_CLKSEL_CON(111), 14, 2, MFLAGS, 9, 5, DFLAGS,
RK3588_CLKGATE_CON(52), 11, GFLAGS),
- COMPOSITE(DCLK_VOP2_SRC, "dclk_vop2_src", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+ COMPOSITE(DCLK_VOP2_SRC, "dclk_vop2_src", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_NO_REPARENT,
RK3588_CLKSEL_CON(112), 5, 2, MFLAGS, 0, 5, DFLAGS,
RK3588_CLKGATE_CON(52), 12, GFLAGS),
COMPOSITE_NODIV(DCLK_VOP0, "dclk_vop0", dclk_vop0_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
@@ -2083,7 +2083,7 @@ static struct rockchip_clk_branch rk3588
COMPOSITE_NODIV(DCLK_VOP2, "dclk_vop2", dclk_vop2_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
RK3588_CLKSEL_CON(112), 11, 2, MFLAGS,
RK3588_CLKGATE_CON(53), 1, GFLAGS),
- COMPOSITE(DCLK_VOP3, "dclk_vop3", gpll_cpll_v0pll_aupll_p, 0,
+ COMPOSITE(DCLK_VOP3, "dclk_vop3", gpll_cpll_v0pll_aupll_p, CLK_SET_RATE_NO_REPARENT,
RK3588_CLKSEL_CON(113), 7, 2, MFLAGS, 0, 7, DFLAGS,
RK3588_CLKGATE_CON(53), 2, GFLAGS),
GATE(PCLK_DSIHOST0, "pclk_dsihost0", "pclk_vop_root", 0,

View file

@ -1,485 +0,0 @@
From bb62799748bd5492d80e9ebee4ac6b5702fb037e Mon Sep 17 00:00:00 2001
From: brooksytech <1673861+brooksytech@users.noreply.github.com>
Date: Wed, 24 Jan 2024 21:50:05 +0000
Subject: [PATCH 14/46] input: add input-polldev driver
---
drivers/input/Kconfig | 13 ++
drivers/input/Makefile | 1 +
drivers/input/input-polldev.c | 362 ++++++++++++++++++++++++++++++++++
include/linux/input-polldev.h | 58 ++++++
4 files changed, 434 insertions(+)
create mode 100644 drivers/input/input-polldev.c
create mode 100644 include/linux/input-polldev.h
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 3bdbd34314b3..779daf5009c1 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -51,6 +51,19 @@ config INPUT_FF_MEMLESS
To compile this driver as a module, choose M here: the
module will be called ff-memless.
+config INPUT_POLLDEV
+ tristate "Polled input device skeleton"
+ help
+ Say Y here if you are using a driver for an input
+ device that periodically polls hardware state. This
+ option is only useful for out-of-tree drivers since
+ in-tree drivers select it automatically.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called input-polldev.
+
config INPUT_SPARSEKMAP
tristate "Sparse keymap support library"
help
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index c78753274921..e92c29174c36 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -10,6 +10,7 @@ input-core-y := input.o input-compat.o input-mt.o input-poller.o ff-core.o
input-core-y += touchscreen.o
obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
+obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
obj-$(CONFIG_INPUT_SPARSEKMAP) += sparse-keymap.o
obj-$(CONFIG_INPUT_MATRIXKMAP) += matrix-keymap.o
obj-$(CONFIG_INPUT_VIVALDIFMAP) += vivaldi-fmap.o
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c
new file mode 100644
index 000000000000..9bf1c9aeb4c4
--- /dev/null
+++ b/drivers/input/input-polldev.c
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Generic implementation of a polled input device
+
+ * Copyright (c) 2007 Dmitry Torokhov
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/input-polldev.h>
+
+MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
+MODULE_DESCRIPTION("Generic implementation of a polled input device");
+MODULE_LICENSE("GPL v2");
+
+static void input_polldev_queue_work(struct input_polled_dev *dev)
+{
+ unsigned long delay;
+
+ delay = msecs_to_jiffies(dev->poll_interval);
+ if (delay >= HZ)
+ delay = round_jiffies_relative(delay);
+
+ queue_delayed_work(system_freezable_wq, &dev->work, delay);
+}
+
+static void input_polled_device_work(struct work_struct *work)
+{
+ struct input_polled_dev *dev =
+ container_of(work, struct input_polled_dev, work.work);
+
+ dev->poll(dev);
+ input_polldev_queue_work(dev);
+}
+
+static int input_open_polled_device(struct input_dev *input)
+{
+ struct input_polled_dev *dev = input_get_drvdata(input);
+
+ if (dev->open)
+ dev->open(dev);
+
+ /* Only start polling if polling is enabled */
+ if (dev->poll_interval > 0) {
+ dev->poll(dev);
+ input_polldev_queue_work(dev);
+ }
+
+ return 0;
+}
+
+static void input_close_polled_device(struct input_dev *input)
+{
+ struct input_polled_dev *dev = input_get_drvdata(input);
+
+ cancel_delayed_work_sync(&dev->work);
+
+ if (dev->close)
+ dev->close(dev);
+}
+
+/* SYSFS interface */
+
+static ssize_t input_polldev_get_poll(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_polled_dev *polldev = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", polldev->poll_interval);
+}
+
+static ssize_t input_polldev_set_poll(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct input_polled_dev *polldev = dev_get_drvdata(dev);
+ struct input_dev *input = polldev->input;
+ unsigned int interval;
+ int err;
+
+ err = kstrtouint(buf, 0, &interval);
+ if (err)
+ return err;
+
+ if (interval < polldev->poll_interval_min)
+ return -EINVAL;
+
+ if (interval > polldev->poll_interval_max)
+ return -EINVAL;
+
+ mutex_lock(&input->mutex);
+
+ polldev->poll_interval = interval;
+
+ if (input->users) {
+ cancel_delayed_work_sync(&polldev->work);
+ if (polldev->poll_interval > 0)
+ input_polldev_queue_work(polldev);
+ }
+
+ mutex_unlock(&input->mutex);
+
+ return count;
+}
+
+static DEVICE_ATTR(poll, S_IRUGO | S_IWUSR, input_polldev_get_poll,
+ input_polldev_set_poll);
+
+
+static ssize_t input_polldev_get_max(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_polled_dev *polldev = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", polldev->poll_interval_max);
+}
+
+static DEVICE_ATTR(max, S_IRUGO, input_polldev_get_max, NULL);
+
+static ssize_t input_polldev_get_min(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_polled_dev *polldev = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", polldev->poll_interval_min);
+}
+
+static DEVICE_ATTR(min, S_IRUGO, input_polldev_get_min, NULL);
+
+static struct attribute *sysfs_attrs[] = {
+ &dev_attr_poll.attr,
+ &dev_attr_max.attr,
+ &dev_attr_min.attr,
+ NULL
+};
+
+static struct attribute_group input_polldev_attribute_group = {
+ .attrs = sysfs_attrs
+};
+
+static const struct attribute_group *input_polldev_attribute_groups[] = {
+ &input_polldev_attribute_group,
+ NULL
+};
+
+/**
+ * input_allocate_polled_device - allocate memory for polled device
+ *
+ * The function allocates memory for a polled device and also
+ * for an input device associated with this polled device.
+ */
+struct input_polled_dev *input_allocate_polled_device(void)
+{
+ struct input_polled_dev *dev;
+
+ dev = kzalloc(sizeof(struct input_polled_dev), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ dev->input = input_allocate_device();
+ if (!dev->input) {
+ kfree(dev);
+ return NULL;
+ }
+
+ return dev;
+}
+EXPORT_SYMBOL(input_allocate_polled_device);
+
+struct input_polled_devres {
+ struct input_polled_dev *polldev;
+};
+
+static int devm_input_polldev_match(struct device *dev, void *res, void *data)
+{
+ struct input_polled_devres *devres = res;
+
+ return devres->polldev == data;
+}
+
+static void devm_input_polldev_release(struct device *dev, void *res)
+{
+ struct input_polled_devres *devres = res;
+ struct input_polled_dev *polldev = devres->polldev;
+
+ dev_dbg(dev, "%s: dropping reference/freeing %s\n",
+ __func__, dev_name(&polldev->input->dev));
+
+ input_put_device(polldev->input);
+ kfree(polldev);
+}
+
+static void devm_input_polldev_unregister(struct device *dev, void *res)
+{
+ struct input_polled_devres *devres = res;
+ struct input_polled_dev *polldev = devres->polldev;
+
+ dev_dbg(dev, "%s: unregistering device %s\n",
+ __func__, dev_name(&polldev->input->dev));
+ input_unregister_device(polldev->input);
+
+ /*
+ * Note that we are still holding extra reference to the input
+ * device so it will stick around until devm_input_polldev_release()
+ * is called.
+ */
+}
+
+/**
+ * devm_input_allocate_polled_device - allocate managed polled device
+ * @dev: device owning the polled device being created
+ *
+ * Returns prepared &struct input_polled_dev or %NULL.
+ *
+ * Managed polled input devices do not need to be explicitly unregistered
+ * or freed as it will be done automatically when owner device unbinds
+ * from * its driver (or binding fails). Once such managed polled device
+ * is allocated, it is ready to be set up and registered in the same
+ * fashion as regular polled input devices (using
+ * input_register_polled_device() function).
+ *
+ * If you want to manually unregister and free such managed polled devices,
+ * it can be still done by calling input_unregister_polled_device() and
+ * input_free_polled_device(), although it is rarely needed.
+ *
+ * NOTE: the owner device is set up as parent of input device and users
+ * should not override it.
+ */
+struct input_polled_dev *devm_input_allocate_polled_device(struct device *dev)
+{
+ struct input_polled_dev *polldev;
+ struct input_polled_devres *devres;
+
+ devres = devres_alloc(devm_input_polldev_release, sizeof(*devres),
+ GFP_KERNEL);
+ if (!devres)
+ return NULL;
+
+ polldev = input_allocate_polled_device();
+ if (!polldev) {
+ devres_free(devres);
+ return NULL;
+ }
+
+ polldev->input->dev.parent = dev;
+ polldev->devres_managed = true;
+
+ devres->polldev = polldev;
+ devres_add(dev, devres);
+
+ return polldev;
+}
+EXPORT_SYMBOL(devm_input_allocate_polled_device);
+
+/**
+ * input_free_polled_device - free memory allocated for polled device
+ * @dev: device to free
+ *
+ * The function frees memory allocated for polling device and drops
+ * reference to the associated input device.
+ */
+void input_free_polled_device(struct input_polled_dev *dev)
+{
+ if (dev) {
+ if (dev->devres_managed)
+ WARN_ON(devres_destroy(dev->input->dev.parent,
+ devm_input_polldev_release,
+ devm_input_polldev_match,
+ dev));
+ input_put_device(dev->input);
+ kfree(dev);
+ }
+}
+EXPORT_SYMBOL(input_free_polled_device);
+
+/**
+ * input_register_polled_device - register polled device
+ * @dev: device to register
+ *
+ * The function registers previously initialized polled input device
+ * with input layer. The device should be allocated with call to
+ * input_allocate_polled_device(). Callers should also set up poll()
+ * method and set up capabilities (id, name, phys, bits) of the
+ * corresponding input_dev structure.
+ */
+int input_register_polled_device(struct input_polled_dev *dev)
+{
+ struct input_polled_devres *devres = NULL;
+ struct input_dev *input = dev->input;
+ int error;
+
+ if (dev->devres_managed) {
+ devres = devres_alloc(devm_input_polldev_unregister,
+ sizeof(*devres), GFP_KERNEL);
+ if (!devres)
+ return -ENOMEM;
+
+ devres->polldev = dev;
+ }
+
+ input_set_drvdata(input, dev);
+ INIT_DELAYED_WORK(&dev->work, input_polled_device_work);
+
+ if (!dev->poll_interval)
+ dev->poll_interval = 500;
+ if (!dev->poll_interval_max)
+ dev->poll_interval_max = dev->poll_interval;
+
+ input->open = input_open_polled_device;
+ input->close = input_close_polled_device;
+
+ input->dev.groups = input_polldev_attribute_groups;
+
+ error = input_register_device(input);
+ if (error) {
+ devres_free(devres);
+ return error;
+ }
+
+ /*
+ * Take extra reference to the underlying input device so
+ * that it survives call to input_unregister_polled_device()
+ * and is deleted only after input_free_polled_device()
+ * has been invoked. This is needed to ease task of freeing
+ * sparse keymaps.
+ */
+ input_get_device(input);
+
+ if (dev->devres_managed) {
+ dev_dbg(input->dev.parent, "%s: registering %s with devres.\n",
+ __func__, dev_name(&input->dev));
+ devres_add(input->dev.parent, devres);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(input_register_polled_device);
+
+/**
+ * input_unregister_polled_device - unregister polled device
+ * @dev: device to unregister
+ *
+ * The function unregisters previously registered polled input
+ * device from input layer. Polling is stopped and device is
+ * ready to be freed with call to input_free_polled_device().
+ */
+void input_unregister_polled_device(struct input_polled_dev *dev)
+{
+ if (dev->devres_managed)
+ WARN_ON(devres_destroy(dev->input->dev.parent,
+ devm_input_polldev_unregister,
+ devm_input_polldev_match,
+ dev));
+
+ input_unregister_device(dev->input);
+}
+EXPORT_SYMBOL(input_unregister_polled_device);
diff --git a/include/linux/input-polldev.h b/include/linux/input-polldev.h
new file mode 100644
index 000000000000..14821fd231c0
--- /dev/null
+++ b/include/linux/input-polldev.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _INPUT_POLLDEV_H
+#define _INPUT_POLLDEV_H
+
+/*
+ * Copyright (c) 2007 Dmitry Torokhov
+ */
+
+#include <linux/input.h>
+#include <linux/workqueue.h>
+
+/**
+ * struct input_polled_dev - simple polled input device
+ * @private: private driver data.
+ * @open: driver-supplied method that prepares device for polling
+ * (enabled the device and maybe flushes device state).
+ * @close: driver-supplied method that is called when device is no
+ * longer being polled. Used to put device into low power mode.
+ * @poll: driver-supplied method that polls the device and posts
+ * input events (mandatory).
+ * @poll_interval: specifies how often the poll() method should be called.
+ * Defaults to 500 msec unless overridden when registering the device.
+ * @poll_interval_max: specifies upper bound for the poll interval.
+ * Defaults to the initial value of @poll_interval.
+ * @poll_interval_min: specifies lower bound for the poll interval.
+ * Defaults to 0.
+ * @input: input device structure associated with the polled device.
+ * Must be properly initialized by the driver (id, name, phys, bits).
+ *
+ * Polled input device provides a skeleton for supporting simple input
+ * devices that do not raise interrupts but have to be periodically
+ * scanned or polled to detect changes in their state.
+ */
+struct input_polled_dev {
+ void *private;
+
+ void (*open)(struct input_polled_dev *dev);
+ void (*close)(struct input_polled_dev *dev);
+ void (*poll)(struct input_polled_dev *dev);
+ unsigned int poll_interval; /* msec */
+ unsigned int poll_interval_max; /* msec */
+ unsigned int poll_interval_min; /* msec */
+
+ struct input_dev *input;
+
+/* private: */
+ struct delayed_work work;
+
+ bool devres_managed;
+};
+
+struct input_polled_dev *input_allocate_polled_device(void);
+struct input_polled_dev *devm_input_allocate_polled_device(struct device *dev);
+void input_free_polled_device(struct input_polled_dev *dev);
+int input_register_polled_device(struct input_polled_dev *dev);
+void input_unregister_polled_device(struct input_polled_dev *dev);
+
+#endif
--
2.34.1

View file

@ -1,14 +1,14 @@
diff -rupN linux.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c linux/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
--- linux.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 2024-02-21 01:57:24.081594191 +0000
+++ linux/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 2024-02-23 14:30:21.801129014 +0000
@@ -4884,8 +4884,8 @@ static int vop2_plane_atomic_check(struc
--- linux.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 2024-03-07 05:53:01.096433183 +0000
+++ linux/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 2024-03-07 05:55:10.999624906 +0000
@@ -4857,8 +4857,8 @@ static int vop2_plane_atomic_check(struc
if (vop2_cluster_window(win) && !vpstate->afbc_en &&
(win->supported_rotations & pstate->rotation)) {
(win->supported_rotations & state->rotation)) {
- DRM_ERROR("Unsupported linear rotation(%d) format at %s\n",
- pstate->rotation, win->name);
- state->rotation, win->name);
+ //DRM_ERROR("Unsupported linear rotation(%d) format at %s\n",
+ // pstate->rotation, win->name);
+ // state->rotation, win->name);
return -EINVAL;
}
}