mirror of
https://github.com/LibreELEC/LibreELEC.tv
synced 2025-09-24 19:46:01 +07:00
Merge pull request #10478 from chewitt/amlogic-upstream
Amlogic: bump kernel and rework tm16xx driver package to be a system service
This commit is contained in:
@@ -41,17 +41,6 @@ show_config() {
|
||||
config_message+="\n - Local Ccache:\t\t\t ${LOCAL_CCACHE:-no}"
|
||||
config_message+="\n - CONFIG_SHELL:\t\t\t ${CONFIG_SHELL:-auto}"
|
||||
|
||||
# Image Filsystem
|
||||
|
||||
config_message+="\n\n Image Filesystems:"
|
||||
config_message+="\n $dashes$dashes"
|
||||
config_message+="\n - Flash Size (MiB): \t\t\t $SYSTEM_SIZE"
|
||||
config_message+="\n - Storage Size (MiB): \t\t\t $STORAGE_SIZE"
|
||||
config_message+="\n - SquashFS Compression Method: \t $SQUASHFS_COMPRESSION"
|
||||
if [ -n "${SQUASHFS_COMPRESSION_OPTION}" ]; then
|
||||
config_message+="\n - SquashFS Compression Options: \t $SQUASHFS_COMPRESSION_OPTION"
|
||||
fi
|
||||
|
||||
# Misc. hardware configuration
|
||||
|
||||
config_message+="\n\n Misc. hardware configuration:"
|
||||
@@ -60,6 +49,7 @@ show_config() {
|
||||
config_message+="\n - ALSA support:\t\t\t ${ALSA_SUPPORT}"
|
||||
config_message+="\n - Pulseaudio support:\t\t\t ${PULSEAUDIO_SUPPORT}"
|
||||
config_message+="\n - Bluetooth support:\t\t\t ${BLUETOOTH_SUPPORT}"
|
||||
config_message+="\n - VFD panel support:\t\t\t ${VFD_SUPPORT}"
|
||||
|
||||
for config_driver in ${ADDITIONAL_DRIVERS}; do
|
||||
config_message+="\n - Include driver:\t\t\t ${config_driver}"
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
DISTRO_BOOTLABEL="LEIOT"
|
||||
DISTRO_DISKLABEL="STORAGE"
|
||||
|
||||
# VFD panel boot message (use UPPERCASE and padding)
|
||||
VFD_MESSAGE=" LEIoT"
|
||||
|
||||
### BUILDSYSTEM SETTINGS ####
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
DISTRO_BOOTLABEL="LIBREELEC"
|
||||
DISTRO_DISKLABEL="STORAGE"
|
||||
|
||||
# VFD panel boot message (use UPPERCASE and padding)
|
||||
VFD_MESSAGE=" LIBREELEC"
|
||||
|
||||
### BUILDSYSTEM SETTINGS ####
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2025-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
PKG_NAME="tm16xx"
|
||||
PKG_VERSION="9148a4e12ba6cf4b375a7fd352667f7f27823426"
|
||||
PKG_SHA256="e8fbbc5c8c36b3eb42f1f8d7c907106ccf3a2b5af4b2382c6ca4ea63e07fde70"
|
||||
PKG_LICENSE="GPLv2"
|
||||
PKG_SITE="https://github.com/jefflessard/tm16xx-display/"
|
||||
PKG_URL="https://github.com/jefflessard/tm16xx-display/archive/${PKG_VERSION}.tar.gz"
|
||||
PKG_LONGDESC="Linux kernel driver for auxiliary displays using TM1628 compatible controllers"
|
||||
PKG_IS_KERNEL_PKG="yes"
|
||||
|
||||
pre_make_target() {
|
||||
unset LDFLAGS
|
||||
}
|
||||
|
||||
make_target() {
|
||||
kernel_make V=1 KDIR=$(kernel_path) module
|
||||
}
|
||||
|
||||
makeinstall_target() {
|
||||
mkdir -p ${INSTALL}/$(get_full_module_dir)/${PKG_NAME}
|
||||
cp *.ko ${INSTALL}/$(get_full_module_dir)/${PKG_NAME}
|
||||
mkdir -p ${INSTALL}/usr/sbin
|
||||
cp display-service ${INSTALL}/usr/sbin
|
||||
cp display-utils ${INSTALL}/usr/sbin
|
||||
mkdir -p ${INSTALL}/usr/lib/systemd/system
|
||||
cp display.service ${INSTALL}/usr/lib/systemd/system
|
||||
}
|
||||
|
||||
post_install() {
|
||||
enable_service display.service
|
||||
}
|
||||
@@ -16,8 +16,8 @@ PKG_PATCH_DIRS="${LINUX}"
|
||||
|
||||
case "${LINUX}" in
|
||||
amlogic)
|
||||
PKG_VERSION="86731a2a651e58953fc949573895f2fa6d456841" # 6.16-rc3
|
||||
PKG_SHA256="008b00968a8bfc0627580b82a2d30c7304336a4f92a58e80cdbc2d4723e01840"
|
||||
PKG_VERSION="4645fefac0b24d509b962c096b0327e87f34b1d2" # 6.16.5
|
||||
PKG_SHA256="45daac22ef696b17041b0ef1584332a255c6f3d26bd604f7052b1f9e65bf13f0"
|
||||
PKG_URL="https://github.com/torvalds/linux/archive/${PKG_VERSION}.tar.gz"
|
||||
PKG_SOURCE_NAME="linux-${LINUX}-${PKG_VERSION}.tar.gz"
|
||||
PKG_PATCH_DIRS="default rtlwifi/6.17"
|
||||
@@ -147,6 +147,27 @@ pre_make_target() {
|
||||
${PKG_BUILD}/scripts/config --disable CONFIG_WIREGUARD
|
||||
fi
|
||||
|
||||
# disable vfd support if not enabled
|
||||
if [ ! "${VFD_SUPPORT}" = yes ]; then
|
||||
${PKG_BUILD}/scripts/config --disable CONFIG_PANEL_CHANGE_MESSAGE
|
||||
else
|
||||
# enable the module and set distro boot message
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_AUXDISPLAY
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_LINEDISPLAY
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_TM16XX
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_TM16XX_KEYPAD
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_TM16XX_I2C
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_TM16XX_SPI
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_PANEL_CHANGE_MESSAGE
|
||||
${PKG_BUILD}/scripts/config --set-str CONFIG_PANEL_BOOT_MESSAGE "${VFD_MESSAGE}"
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_INPUT_MATRIXKMAP
|
||||
# enable led activity triggers
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_LEDS_TRIGGER_TIMER # Colon
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_LEDS_TRIGGER_NETDEV # LAN/WLAN
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_USB_LEDS_TRIGGER_USBPORT # USB
|
||||
${PKG_BUILD}/scripts/config --enable CONFIG_MMC # SD
|
||||
fi
|
||||
|
||||
if [ "${TARGET_ARCH}" = "x86_64" ]; then
|
||||
# copy some extra firmware to linux tree
|
||||
mkdir -p ${PKG_BUILD}/external-firmware
|
||||
|
||||
23
packages/sysutils/tm16xx-display/package.mk
Normal file
23
packages/sysutils/tm16xx-display/package.mk
Normal file
@@ -0,0 +1,23 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (C) 2025-present Team LibreELEC (https://libreelec.tv)
|
||||
|
||||
PKG_NAME="tm16xx-display"
|
||||
PKG_VERSION="e990a0cc2377fb957973dd406db6ab6fdf9c2a5a" #v4-feedback
|
||||
PKG_SHA256="2b9c53f87641c7498d384d97b4e3605eda8a6a0b76e2b6ad4c916551829e6207"
|
||||
PKG_LICENSE="GPLv2"
|
||||
PKG_SITE="https://github.com/jefflessard/tm16xx-display/"
|
||||
PKG_URL="https://github.com/jefflessard/tm16xx-display/archive/${PKG_VERSION}.tar.gz"
|
||||
PKG_LONGDESC="Linux kernel driver utilities for TM16XX compatible controllers"
|
||||
PKG_IS_KERNEL_PKG="yes"
|
||||
PKG_TOOLCHAIN="manual"
|
||||
|
||||
post_makeinstall_target() {
|
||||
mkdir -p ${INSTALL}/usr/sbin
|
||||
cp display-service ${INSTALL}/usr/sbin
|
||||
mkdir -p ${INSTALL}/usr/lib/systemd/system
|
||||
cp display.service ${INSTALL}/usr/lib/systemd/system
|
||||
}
|
||||
|
||||
post_install() {
|
||||
enable_service display.service
|
||||
}
|
||||
@@ -9,3 +9,7 @@ PKG_URL=""
|
||||
PKG_DEPENDS_TARGET="toolchain ${ADDITIONAL_PACKAGES}"
|
||||
PKG_SECTION="virtual"
|
||||
PKG_LONGDESC="misc-packages: Metapackage for miscellaneous packages"
|
||||
|
||||
if [ "${VFD_SUPPORT}" = "yes" ]; then
|
||||
PKG_DEPENDS_TARGET+=" tm16xx-display"
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 9a711d3aca9f7bd053caefec4f1bef07ba1a4817 Mon Sep 17 00:00:00 2001
|
||||
From a1bbdc06d9709b09b40bc973eaf01be7bb2c857f Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Sat, 13 Apr 2019 05:41:51 +0000
|
||||
Subject: [PATCH 01/37] LOCAL: set meson-gx cma pool to 896MB
|
||||
Subject: [PATCH 01/54] LOCAL: set meson-gx cma pool to 896MB
|
||||
|
||||
This change sets the CMA pool to a larger 896MB! value for vdec use
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 5979e28bfa5986d47ba62f147feb5d9b83f16e6d Mon Sep 17 00:00:00 2001
|
||||
From d340a41dc7009e1713862fd604c83d3b32da8a76 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Wed, 14 Aug 2019 19:58:14 +0000
|
||||
Subject: [PATCH 02/37] LOCAL: set meson-g12 cma pool to 896MB
|
||||
Subject: [PATCH 02/54] LOCAL: set meson-g12 cma pool to 896MB
|
||||
|
||||
This change sets the CMA pool to a larger 896MB! value for vdec use
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 3df5b83cf844e053806a57afd5a4af8d11617c5d Mon Sep 17 00:00:00 2001
|
||||
From 0abf689abf81dc2a68f5a7b59367b4a026797692 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Sat, 13 Apr 2019 05:45:18 +0000
|
||||
Subject: [PATCH 03/37] LOCAL: arm64: fix Kodi sysinfo CPU information
|
||||
Subject: [PATCH 03/54] LOCAL: arm64: fix Kodi sysinfo CPU information
|
||||
|
||||
This allows the CPU information to show in the Kodi sysinfo screen, e.g.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From cacea1a7dcf9e69c3d1cfc1026a05a9332bf9837 Mon Sep 17 00:00:00 2001
|
||||
From 0f80ea4c86330ceb491fa0c6fd096386d7cf5038 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
||||
Date: Thu, 3 Nov 2016 15:29:23 +0100
|
||||
Subject: [PATCH 04/37] LOCAL: arm64: meson: add Amlogic Meson GX PM Suspend
|
||||
Subject: [PATCH 04/54] LOCAL: arm64: meson: add Amlogic Meson GX PM Suspend
|
||||
|
||||
The Amlogic Meson GX SoCs uses a non-standard argument to the
|
||||
PSCI CPU_SUSPEND call to enter system suspend.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From ac95c04240bf6d1f12158f819bb9c0a0d06d6653 Mon Sep 17 00:00:00 2001
|
||||
From 30b51e1a9d0c2eb84ea5430bfc9eb68f557295e9 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
||||
Date: Thu, 3 Nov 2016 15:29:25 +0100
|
||||
Subject: [PATCH 05/37] LOCAL: arm64: dts: meson: add support for GX PM and
|
||||
Subject: [PATCH 05/54] LOCAL: arm64: dts: meson: add support for GX PM and
|
||||
Virtual RTC
|
||||
|
||||
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 3198831b6d71337b85e5011fc820ea13057ab3a6 Mon Sep 17 00:00:00 2001
|
||||
From 5d68f74491915ee2eee4f4a2d0e7faf4c618e85b Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Thu, 21 Jan 2021 01:35:36 +0000
|
||||
Subject: [PATCH 06/37] LOCAL: arm64: dts: meson: add rtc/vrtc aliases to
|
||||
Subject: [PATCH 06/54] LOCAL: arm64: dts: meson: add rtc/vrtc aliases to
|
||||
Khadas VIM
|
||||
|
||||
Add aliases to ensure the vrtc time (which normally proves first) is /dev/rtc1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 596472232f2a08c7dd62597c9c041be4333e22b0 Mon Sep 17 00:00:00 2001
|
||||
From 892b686fea1524983532028b064b991acb4a996a Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Sat, 6 Nov 2021 13:01:08 +0000
|
||||
Subject: [PATCH 07/37] LOCAL: arm64: dts: meson: add rtc/vrtc aliases to
|
||||
Subject: [PATCH 07/54] LOCAL: arm64: dts: meson: add rtc/vrtc aliases to
|
||||
Khadas VIM2
|
||||
|
||||
Add aliases to ensure the vrtc time (which normally proves first) is /dev/rtc1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From a8f90df94245a52d5a0aff58a640b5c86e0ed83c Mon Sep 17 00:00:00 2001
|
||||
From 06af057b5f5f54dd41505fdb3f3a8e48a6092830 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Mon, 1 Feb 2021 19:27:40 +0000
|
||||
Subject: [PATCH 08/37] LOCAL: arm64: dts: meson: add rtc/vrtc aliases to Minix
|
||||
Subject: [PATCH 08/54] LOCAL: arm64: dts: meson: add rtc/vrtc aliases to Minix
|
||||
NEO U9-H
|
||||
|
||||
Add node aliases to prevent meson-vrtc from claiming /dev/rtc0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From e751b7cfeaca07cef1b14cebbd4dc567ed50ed37 Mon Sep 17 00:00:00 2001
|
||||
From 80e4f03703c050a8d03f7ea0c1138c52da66e2ea Mon Sep 17 00:00:00 2001
|
||||
From: Anssi Hannula <anssi.hannula@iki.fi>
|
||||
Date: Sun, 17 Apr 2022 04:37:48 +0000
|
||||
Subject: [PATCH 09/37] LOCAL: ASoC: meson: assign internal PCM
|
||||
Subject: [PATCH 09/54] LOCAL: ASoC: meson: assign internal PCM
|
||||
chmap/ELD/IEC958 kctls to device 0
|
||||
|
||||
On SoC sound devices utilizing codec2codec DAI links with an HDMI codec the kctls
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 3de630c16f0ddbaa6442ebc3b6938bc1c4526b34 Mon Sep 17 00:00:00 2001
|
||||
From 417a84f1112d735c667a29041d3a876bc9ebc3d4 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Thu, 5 Jan 2023 15:16:46 +0000
|
||||
Subject: [PATCH 10/37] LOCAL: media: meson: vdec: disable MPEG1/MPEG2 hardware
|
||||
Subject: [PATCH 10/54] LOCAL: media: meson: vdec: disable MPEG1/MPEG2 hardware
|
||||
decoding
|
||||
|
||||
The MPEG1/2 decoder is broken and nobody has volunteered to poke
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 2411a183fc6f2806727cf9dcfe62dcd5e1199ce9 Mon Sep 17 00:00:00 2001
|
||||
From 31d7d59be91e2b2f82ca5e55abd8fb7c2757fdd7 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Sat, 3 May 2025 15:18:07 +0000
|
||||
Subject: [PATCH 17/37] FROMLIST(v1): arm64: dts: amlogic: sm1-bananapi: lower
|
||||
Subject: [PATCH 11/54] FROMGIT(6.18): arm64: dts: amlogic: sm1-bananapi: lower
|
||||
SD card speed for stability
|
||||
|
||||
Users report being able to boot (u-boot) from SD card but kernel
|
||||
@@ -0,0 +1,91 @@
|
||||
From de13bf61677213530ae8ac7813efea3c6991525d Mon Sep 17 00:00:00 2001
|
||||
From: Anand Moon <linux.amoon@gmail.com>
|
||||
Date: Mon, 25 Aug 2025 12:21:41 +0530
|
||||
Subject: [PATCH 12/54] FROMGIT(6.18): arm64: dts: amlogic: Add cache
|
||||
information to the Amlogic GXBB and GXL SoC
|
||||
|
||||
As per S905 and S905X datasheet add missing cache information to
|
||||
the Amlogic GXBB and GXL SoC.
|
||||
|
||||
- Each Cortex-A53 core has 32KB of L1 instruction cache available and
|
||||
32KB of L1 data cache available.
|
||||
- Along with 512KB Unified L2 cache.
|
||||
|
||||
Cache memory significantly reduces the time it takes for the CPU
|
||||
to access data and instructions, leading to faster program execution
|
||||
and overall system responsiveness.
|
||||
|
||||
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 27 +++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
|
||||
index 260628cf218e..1a7333c7da96 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
|
||||
@@ -95,6 +95,12 @@ cpu0: cpu@0 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
clocks = <&scpi_dvfs 0>;
|
||||
#cooling-cells = <2>;
|
||||
@@ -105,6 +111,12 @@ cpu1: cpu@1 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x0 0x1>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
clocks = <&scpi_dvfs 0>;
|
||||
#cooling-cells = <2>;
|
||||
@@ -115,6 +127,12 @@ cpu2: cpu@2 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x0 0x2>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
clocks = <&scpi_dvfs 0>;
|
||||
#cooling-cells = <2>;
|
||||
@@ -125,6 +143,12 @@ cpu3: cpu@3 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x0 0x3>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
clocks = <&scpi_dvfs 0>;
|
||||
#cooling-cells = <2>;
|
||||
@@ -134,6 +158,9 @@ l2: l2-cache0 {
|
||||
compatible = "cache";
|
||||
cache-level = <2>;
|
||||
cache-unified;
|
||||
+ cache-size = <0x80000>; /* L2. 512 KB */
|
||||
+ cache-line-size = <64>;
|
||||
+ cache-sets = <512>;
|
||||
};
|
||||
};
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
From 16c9fa28fcb4a8193fedd2841b317d1384c5be63 Mon Sep 17 00:00:00 2001
|
||||
From: Anand Moon <linux.amoon@gmail.com>
|
||||
Date: Mon, 25 Aug 2025 12:21:45 +0530
|
||||
Subject: [PATCH 13/54] FROMGIT(6.18): arm64: dts: amlogic: Add cache
|
||||
information to the Amlogic GXM SoCS
|
||||
|
||||
As per the GXM datasheet add missing cache information to the Amlogic GXM
|
||||
SoC.
|
||||
|
||||
- Each Cortex-A53 core has 32KB of L1 instruction cache available and
|
||||
32KB of L1 data cache available.
|
||||
- Along with 512KB Unified L2 cache.
|
||||
|
||||
Cache memory significantly reduces the time it takes for the CPU
|
||||
to access data and instructions, leading to faster program execution
|
||||
and overall system responsiveness.
|
||||
|
||||
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/amlogic/meson-gxm.dtsi | 24 ++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
|
||||
index 411cc312fc62..514c9bea6423 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
|
||||
@@ -64,6 +64,12 @@ cpu4: cpu@100 {
|
||||
reg = <0x0 0x100>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
clocks = <&scpi_dvfs 1>;
|
||||
#cooling-cells = <2>;
|
||||
@@ -75,6 +81,12 @@ cpu5: cpu@101 {
|
||||
reg = <0x0 0x101>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
clocks = <&scpi_dvfs 1>;
|
||||
#cooling-cells = <2>;
|
||||
@@ -86,6 +98,12 @@ cpu6: cpu@102 {
|
||||
reg = <0x0 0x102>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
clocks = <&scpi_dvfs 1>;
|
||||
#cooling-cells = <2>;
|
||||
@@ -97,6 +115,12 @@ cpu7: cpu@103 {
|
||||
reg = <0x0 0x103>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
clocks = <&scpi_dvfs 1>;
|
||||
#cooling-cells = <2>;
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
From 8f6a387b7ad84170a309872f72b586f4c8a38d31 Mon Sep 17 00:00:00 2001
|
||||
From: Anand Moon <linux.amoon@gmail.com>
|
||||
Date: Mon, 25 Aug 2025 12:21:43 +0530
|
||||
Subject: [PATCH 14/54] FROMGIT(6.18): arm64: dts: amlogic: Add cache
|
||||
information to the Amlogic G12A SoCS
|
||||
|
||||
As per the S905X2 datasheet add missing cache information to the Amlogic
|
||||
G12A SoC.
|
||||
|
||||
- Each Cortex-A53 core has 32KB of L1 instruction cache available and
|
||||
32KB of L1 data cache available.
|
||||
- Along with 512KB Unified L2 cache.
|
||||
|
||||
Cache memory significantly reduces the time it takes for the CPU
|
||||
to access data and instructions, leading to faster program execution
|
||||
and overall system responsiveness.
|
||||
|
||||
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/amlogic/meson-g12a.dtsi | 27 +++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
|
||||
index deee61dbe074..1321ad95923d 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
|
||||
@@ -17,6 +17,12 @@ cpu0: cpu@0 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@@ -26,6 +32,12 @@ cpu1: cpu@1 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x0 0x1>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@@ -35,6 +47,12 @@ cpu2: cpu@2 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x0 0x2>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@@ -44,6 +62,12 @@ cpu3: cpu@3 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x0 0x3>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@@ -52,6 +76,9 @@ l2: l2-cache0 {
|
||||
compatible = "cache";
|
||||
cache-level = <2>;
|
||||
cache-unified;
|
||||
+ cache-size = <0x80000>; /* L2. 512 KB */
|
||||
+ cache-line-size = <64>;
|
||||
+ cache-sets = <512>;
|
||||
};
|
||||
};
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
From fd85ad679733c0affc0fa89606a3c6f7e7d1280f Mon Sep 17 00:00:00 2001
|
||||
From: Anand Moon <linux.amoon@gmail.com>
|
||||
Date: Mon, 25 Aug 2025 12:21:50 +0530
|
||||
Subject: [PATCH 15/54] FROMGIT(6.18): arm64: dts: amlogic: Add cache
|
||||
information to the Amlogic S922X SoC
|
||||
|
||||
As per S922X datasheet add missing cache information to the Amlogic
|
||||
S922X SoC.
|
||||
|
||||
- Each Cortex-A53 core has 32 KB of instruction cache and
|
||||
32 KB of L1 data cache available.
|
||||
- Each Cortex-A73 core has 64 KB of L1 instruction cache and
|
||||
64 KB of L1 data cache available.
|
||||
- The little (A53) cluster has 256 KB of unified L2 cache available.
|
||||
- The big (A73) cluster has 1 MB of unified L2 cache available.
|
||||
|
||||
Cache memory significantly reduces the time it takes for the CPU
|
||||
to access data and instructions, leading to faster program execution
|
||||
and overall system responsiveness.
|
||||
|
||||
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/amlogic/meson-g12b.dtsi | 62 ++++++++++++++++++---
|
||||
1 file changed, 55 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
|
||||
index 86e6ceb31d5e..f04efa828256 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
|
||||
@@ -49,7 +49,13 @@ cpu0: cpu@0 {
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <592>;
|
||||
- next-level-cache = <&l2>;
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
+ next-level-cache = <&l2_cache_l>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -59,7 +65,13 @@ cpu1: cpu@1 {
|
||||
reg = <0x0 0x1>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <592>;
|
||||
- next-level-cache = <&l2>;
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
+ next-level-cache = <&l2_cache_l>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -69,7 +81,13 @@ cpu100: cpu@100 {
|
||||
reg = <0x0 0x100>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
- next-level-cache = <&l2>;
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
+ next-level-cache = <&l2_cache_l>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -79,7 +97,13 @@ cpu101: cpu@101 {
|
||||
reg = <0x0 0x101>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
- next-level-cache = <&l2>;
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
+ next-level-cache = <&l2_cache_l>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -89,7 +113,13 @@ cpu102: cpu@102 {
|
||||
reg = <0x0 0x102>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
- next-level-cache = <&l2>;
|
||||
+ d-cache-line-size = <64>;
|
||||
+ d-cache-size = <0x10000>;
|
||||
+ d-cache-sets = <64>;
|
||||
+ i-cache-line-size = <64>;
|
||||
+ i-cache-size = <0x10000>;
|
||||
+ i-cache-sets = <64>;
|
||||
+ next-level-cache = <&l2_cache_b>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
@@ -99,14 +129,32 @@ cpu103: cpu@103 {
|
||||
reg = <0x0 0x103>;
|
||||
enable-method = "psci";
|
||||
capacity-dmips-mhz = <1024>;
|
||||
- next-level-cache = <&l2>;
|
||||
+ d-cache-line-size = <64>;
|
||||
+ d-cache-size = <0x10000>;
|
||||
+ d-cache-sets = <64>;
|
||||
+ i-cache-line-size = <64>;
|
||||
+ i-cache-size = <0x10000>;
|
||||
+ i-cache-sets = <64>;
|
||||
+ next-level-cache = <&l2_cache_b>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
|
||||
- l2: l2-cache0 {
|
||||
+ l2_cache_l: l2-cache-cluster0 {
|
||||
compatible = "cache";
|
||||
cache-level = <2>;
|
||||
cache-unified;
|
||||
+ cache-size = <0x40000>; /* L2. 256 KB */
|
||||
+ cache-line-size = <64>;
|
||||
+ cache-sets = <512>;
|
||||
+ };
|
||||
+
|
||||
+ l2_cache_b: l2-cache-cluster1 {
|
||||
+ compatible = "cache";
|
||||
+ cache-level = <2>;
|
||||
+ cache-unified;
|
||||
+ cache-size = <0x100000>; /* L2. 1MB */
|
||||
+ cache-line-size = <64>;
|
||||
+ cache-sets = <512>;
|
||||
};
|
||||
};
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
From 3db85f2107f75df070f04c8a4c1291de62ae9f41 Mon Sep 17 00:00:00 2001
|
||||
From: Anand Moon <linux.amoon@gmail.com>
|
||||
Date: Mon, 25 Aug 2025 12:21:42 +0530
|
||||
Subject: [PATCH 16/54] FROMGIT(6.18): arm64: dts: amlogic: Add cache
|
||||
information to the Amlogic SM1 SoC
|
||||
|
||||
As per S905X3 datasheet add missing cache information to the Amlogic
|
||||
SM1 SoC. ARM Cortex-A55 CPU uses unified L3 cache instead of L2 cache.
|
||||
|
||||
- Each Cortex-A55 core has 32KB of L1 instruction cache available and
|
||||
32KB of L1 data cache available.
|
||||
- Along with 256KB Unified L2 cache.
|
||||
|
||||
Cache memory significantly reduces the time it takes for the CPU
|
||||
to access data and instructions, leading to faster program execution
|
||||
and overall system responsiveness.
|
||||
|
||||
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 27 ++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
|
||||
index 966ebb19cc55..e5db8ce94062 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
|
||||
@@ -55,6 +55,12 @@ cpu0: cpu@0 {
|
||||
compatible = "arm,cortex-a55";
|
||||
reg = <0x0 0x0>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@@ -64,6 +70,12 @@ cpu1: cpu@1 {
|
||||
compatible = "arm,cortex-a55";
|
||||
reg = <0x0 0x1>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@@ -73,6 +85,12 @@ cpu2: cpu@2 {
|
||||
compatible = "arm,cortex-a55";
|
||||
reg = <0x0 0x2>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@@ -82,6 +100,12 @@ cpu3: cpu@3 {
|
||||
compatible = "arm,cortex-a55";
|
||||
reg = <0x0 0x3>;
|
||||
enable-method = "psci";
|
||||
+ d-cache-line-size = <32>;
|
||||
+ d-cache-size = <0x8000>;
|
||||
+ d-cache-sets = <32>;
|
||||
+ i-cache-line-size = <32>;
|
||||
+ i-cache-size = <0x8000>;
|
||||
+ i-cache-sets = <32>;
|
||||
next-level-cache = <&l2>;
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@@ -90,6 +114,9 @@ l2: l2-cache0 {
|
||||
compatible = "cache";
|
||||
cache-level = <2>;
|
||||
cache-unified;
|
||||
+ cache-size = <0x40000>; /* L2. 256 KB */
|
||||
+ cache-line-size = <64>;
|
||||
+ cache-sets = <256>;
|
||||
};
|
||||
};
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 4c895bf75fbf67654d02032cfbdfa57fa4777b20 Mon Sep 17 00:00:00 2001
|
||||
From 8708229747c8a0ee991f8910f2de1a6c5bb18f8c Mon Sep 17 00:00:00 2001
|
||||
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
Date: Wed, 9 Apr 2025 23:44:22 +0200
|
||||
Subject: [PATCH 11/37] FROMLIST(v1): drm/meson: fix resource cleanup in
|
||||
Subject: [PATCH 17/54] FROMLIST(v1): drm/meson: fix resource cleanup in
|
||||
meson_drv_bind_master() on error
|
||||
|
||||
meson_drv_bind_master() does not free resources in the order they are
|
||||
@@ -1,7 +1,7 @@
|
||||
From 6745bff6c6c1ee1746c955504a3ea32d12ec8d79 Mon Sep 17 00:00:00 2001
|
||||
From 4357de91175470f8215a944344682f4c74a6166e Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Kunbo <zhangkunbo@huawei.com>
|
||||
Date: Wed, 6 Nov 2024 02:45:48 +0000
|
||||
Subject: [PATCH 12/37] FROMLIST(v1): drm/meson: Avoid use-after-free issues
|
||||
Subject: [PATCH 18/54] FROMLIST(v1): drm/meson: Avoid use-after-free issues
|
||||
with crtc
|
||||
|
||||
It's dangerous to call drm_crtc_init_with_planes() whose second
|
||||
@@ -1,7 +1,7 @@
|
||||
From 4babe8c6a677ed0f21cf518c8ce78caecc8963b8 Mon Sep 17 00:00:00 2001
|
||||
From d8c2c6a0c399bfa68a30f34e7a75785df3a9ace5 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Fri, 7 Feb 2025 04:29:08 +0000
|
||||
Subject: [PATCH 13/37] FROMLIST(v2): media: si2168: increase cmd execution
|
||||
Subject: [PATCH 19/54] FROMLIST(v2): media: si2168: increase cmd execution
|
||||
timeout value
|
||||
|
||||
Testing with a MyGica T230C v2 USB device (0572:c68a) shows occasional
|
||||
@@ -1,7 +1,7 @@
|
||||
From 3eb58e53708f534a47f4cccbd44efa36d5584a5c Mon Sep 17 00:00:00 2001
|
||||
From 1a27ead3707a6b7148adefdf2c0a68a37097cd69 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
||||
Date: Mon, 22 Nov 2021 09:15:21 +0000
|
||||
Subject: [PATCH 14/37] FROMLIST(v1): media: meson: vdec: esparser: check
|
||||
Subject: [PATCH 20/54] FROMLIST(v1): media: meson: vdec: esparser: check
|
||||
parsing state with hardware write pointer
|
||||
|
||||
Also check the hardware write pointer to check if ES Parser has stalled.
|
||||
@@ -1,7 +1,7 @@
|
||||
From 61874bc3835b2326bb40bae200888657e7d38fa3 Mon Sep 17 00:00:00 2001
|
||||
From 48ea645056a1d006d46dd4bb13320d2e0e5dac19 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Roszak <benjamin545@gmail.com>
|
||||
Date: Mon, 23 Jan 2023 10:56:46 +0000
|
||||
Subject: [PATCH 15/37] FROMLIST(v2): media: meson: vdec: implement 10bit
|
||||
Subject: [PATCH 21/54] FROMLIST(v2): media: meson: vdec: implement 10bit
|
||||
bitstream handling
|
||||
|
||||
In order to support 10bit bitstream decoding, buffers and MMU
|
||||
@@ -1,7 +1,7 @@
|
||||
From befb64847f9d38e20a38ed9ca3e351a4d80e9d05 Mon Sep 17 00:00:00 2001
|
||||
From 0e174d88c295f45627b09163ea74f52ad25259b1 Mon Sep 17 00:00:00 2001
|
||||
From: Maxime Jourdan <mjourdan@baylibre.com>
|
||||
Date: Mon, 23 Jan 2023 11:07:04 +0000
|
||||
Subject: [PATCH 16/37] FROMLIST(v2): media: meson: vdec: add HEVC decode codec
|
||||
Subject: [PATCH 22/54] FROMLIST(v2): media: meson: vdec: add HEVC decode codec
|
||||
|
||||
Add initial HEVC codec for the Amlogic GXBB/GXL/GXM SoCs using
|
||||
the common "HEVC" decoder driver.
|
||||
@@ -1,7 +1,7 @@
|
||||
From a1f197da3061f0ccf210e7b69c478e31377196c4 Mon Sep 17 00:00:00 2001
|
||||
From ca6474af65e4e4b9150cce40ef16fee0985538fc Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Baierl <ichgeh@imkreisrum.de>
|
||||
Date: Tue, 2 Apr 2024 14:22:52 +0000
|
||||
Subject: [PATCH 18/37] WIP: media: meson: vdec: reintroduce wiggle room
|
||||
Subject: [PATCH 23/54] WIP: media: meson: vdec: reintroduce wiggle room
|
||||
|
||||
Without the wiggle room, it happens that matching offsets can't be found.
|
||||
This results in non-matches and afterwards in frame drops in userspace apps.
|
||||
@@ -1,7 +1,7 @@
|
||||
From e0ebd51471f1153d3d1dc53b9a645fde537b1411 Mon Sep 17 00:00:00 2001
|
||||
From a87972cd735bd7a0360094e4e81095aaff4c76bf Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Tue, 14 Mar 2023 01:13:15 +0000
|
||||
Subject: [PATCH 19/37] WIP: media: meson: vdec: fix memory leak of 'new_frame'
|
||||
Subject: [PATCH 24/54] WIP: media: meson: vdec: fix memory leak of 'new_frame'
|
||||
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Reported-by: Dan Carpenter <error27@gmail.com>
|
||||
@@ -1,7 +1,7 @@
|
||||
From 32d8e8ef41de29cfede75a4eed0f33fa4d326057 Mon Sep 17 00:00:00 2001
|
||||
From 2b570713704be6a255eae94dd4e3f4b40a60024a Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Baierl <ichgeh@imkreisrum.de>
|
||||
Date: Thu, 20 Feb 2025 23:59:14 +0000
|
||||
Subject: [PATCH 20/37] WIP: media: meson: vdec: fix
|
||||
Subject: [PATCH 25/54] WIP: media: meson: vdec: fix
|
||||
V4L2_BUF_FLAG_{KEY|P|B}FRAME
|
||||
|
||||
ffmpeg needs the keyframe flag to be set correctly, else
|
||||
@@ -1,7 +1,7 @@
|
||||
From 2efb62e0eaeeb3d2c84b7d12c94a5ba99c257b06 Mon Sep 17 00:00:00 2001
|
||||
From c9aa6d082e3cfd6c90648519cf6a00a188552d59 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Sun, 26 May 2024 12:53:07 +0000
|
||||
Subject: [PATCH 21/37] WIP: arm64: dts: meson: add Odroid-C2 HiFi-Shield
|
||||
Subject: [PATCH 26/54] WIP: arm64: dts: meson: add Odroid-C2 HiFi-Shield
|
||||
boards
|
||||
|
||||
Add experimental device-tree files for Odroid C2 with HiFi-Shield+ (pcm5102a)
|
||||
@@ -1,7 +1,7 @@
|
||||
From 21708d1bcb84d0d8260c143746df5bff8dbe7a77 Mon Sep 17 00:00:00 2001
|
||||
From c0d104a2891ffdeb6c0746636a4b993ae639613c Mon Sep 17 00:00:00 2001
|
||||
From: Da Xue <da@libre.computer>
|
||||
Date: Tue, 8 Aug 2023 01:00:15 -0400
|
||||
Subject: [PATCH 22/37] WIP: net: phy: meson-gxl: implement
|
||||
Subject: [PATCH 27/54] WIP: net: phy: meson-gxl: implement
|
||||
meson_gxl_phy_resume()
|
||||
|
||||
While testing the suspend/resume functionality, we found the ethernet
|
||||
@@ -1,7 +1,7 @@
|
||||
From 71facc1a41966252fd3368b8a6cfc02d3e91d85a Mon Sep 17 00:00:00 2001
|
||||
From 00dc3a05e11e2930fa13bac35765a3ce6c596808 Mon Sep 17 00:00:00 2001
|
||||
From: Dongjin Kim <tobetter@gmail.com>
|
||||
Date: Thu, 10 Sep 2020 11:01:33 +0900
|
||||
Subject: [PATCH 23/37] WIP: drm/meson: add support for 2560x1440 resolution
|
||||
Subject: [PATCH 28/54] WIP: drm/meson: add support for 2560x1440 resolution
|
||||
output
|
||||
|
||||
Add support for Quad HD (QHD) 2560x1440 resolution output. Timings
|
||||
@@ -1,7 +1,7 @@
|
||||
From 5d95e031c6517a910173b80c50b800ffdc6493fa Mon Sep 17 00:00:00 2001
|
||||
From 161d4ce0a257f861369c51dbe06f8291c41943c6 Mon Sep 17 00:00:00 2001
|
||||
From: Luke Lu <luke.lu@libre.computer>
|
||||
Date: Mon, 21 Aug 2023 10:50:04 +0000
|
||||
Subject: [PATCH 24/37] WIP: drm/meson: do setup after resumption to fix hdmi
|
||||
Subject: [PATCH 29/54] WIP: drm/meson: do setup after resumption to fix hdmi
|
||||
output
|
||||
|
||||
Some HDMI displays connected to gxl-based boards go black after
|
||||
@@ -1,7 +1,7 @@
|
||||
From b31529fd0ef42632387ce46def44a4e847d88ce1 Mon Sep 17 00:00:00 2001
|
||||
From 2786ea5c4c7517cd23fdef585261a6ed18349058 Mon Sep 17 00:00:00 2001
|
||||
From: Luke Lu <luke.lu@libre.computer>
|
||||
Date: Wed, 13 Dec 2023 03:47:44 +0000
|
||||
Subject: [PATCH 25/37] WIP: drm/meson: poweron/off dw_hdmi only if dw_hdmi
|
||||
Subject: [PATCH 30/54] WIP: drm/meson: poweron/off dw_hdmi only if dw_hdmi
|
||||
enabled
|
||||
|
||||
dw_hdmi_poweron() assumes that hdmi->curr_conn is valid. Calling
|
||||
@@ -1,7 +1,7 @@
|
||||
From b2f06cfdd0e7d396d51aa733597f2a6631a4dc8c Mon Sep 17 00:00:00 2001
|
||||
From 4527300ce59f7832cf0f572e95841bf4e709f09b Mon Sep 17 00:00:00 2001
|
||||
From: Da Xue <da@libre.computer>
|
||||
Date: Sun, 22 Jun 2025 17:46:21 -0400
|
||||
Subject: [PATCH 26/37] WIP: mmc: meson-gx-mmc: add delay during poweroff
|
||||
Subject: [PATCH 31/54] WIP: mmc: meson-gx-mmc: add delay during poweroff
|
||||
|
||||
---
|
||||
drivers/mmc/host/meson-gx-mmc.c | 1 +
|
||||
@@ -1,7 +1,7 @@
|
||||
From 59614ff80eb272009bc6bdfcb47e8df6ec93a2a7 Mon Sep 17 00:00:00 2001
|
||||
From 5930c4938e460edb1077c4b98a05e871e5a1329f Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Tue, 18 Jan 2022 15:09:12 +0000
|
||||
Subject: [PATCH 27/37] WIP: arm64: dts: meson: set p212/p23x/q20x SDIO to
|
||||
Subject: [PATCH 32/54] WIP: arm64: dts: meson: set p212/p23x/q20x SDIO to
|
||||
100MHz
|
||||
|
||||
Amlogic datasheets describe 50MHz max-frequency for SDIO on GXL/GXM but
|
||||
@@ -1,29 +0,0 @@
|
||||
From bb0a8ba6c365a8dd979f2e3d040f565a1d1f36b0 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Sun, 20 Feb 2022 08:23:12 +0000
|
||||
Subject: [PATCH 32/37] WIP: dt-bindings: vendor-prefixes: add Titan Micro
|
||||
Electronics
|
||||
|
||||
Add a vendor prefix for Shenzhen Titan Micro Electronics Co., Ltd.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <christianshewitt@gmail.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
index 5d2a7a8d3ac6..32f8f24ec809 100644
|
||||
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
@@ -1548,6 +1548,8 @@ patternProperties:
|
||||
description: Texas Instruments
|
||||
"^tianma,.*":
|
||||
description: Tianma Micro-electronics Co., Ltd.
|
||||
+ "^titanmec,.*":
|
||||
+ description: Shenzhen Titan Micro Electronics Co., Ltd.
|
||||
"^tlm,.*":
|
||||
description: Trusted Logic Mobility
|
||||
"^tmt,.*":
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 087bb82aefa86c31f4ea92774452392763a4c83b Mon Sep 17 00:00:00 2001
|
||||
From 2c0f812be6825d1cff2ee697e6ec0b261c04a02f Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Tue, 18 Jan 2022 15:18:32 +0000
|
||||
Subject: [PATCH 28/37] WIP: arm64: dts: meson: remove SDIO node from Khadas
|
||||
Subject: [PATCH 33/54] WIP: arm64: dts: meson: remove SDIO node from Khadas
|
||||
VIM1
|
||||
|
||||
Now that SDIO 100MHz max-frequency is inherited from the p212 dtsi we
|
||||
@@ -1,29 +0,0 @@
|
||||
From ea1f663261cea2fe53626fd2d96c5e8b4d475e28 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Thu, 12 Jun 2025 10:25:29 +0000
|
||||
Subject: [PATCH 33/37] WIP: dt-bindings: vendor-prefixes: add Fuda Hisi
|
||||
Microelectronics
|
||||
|
||||
Add the "fdhisi" prefix for Fuda Hisi Microelectronics Co, Ltd.
|
||||
|
||||
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
index 32f8f24ec809..d02615496b2b 100644
|
||||
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
@@ -531,6 +531,8 @@ patternProperties:
|
||||
description: Fastrax Oy
|
||||
"^fcs,.*":
|
||||
description: Fairchild Semiconductor
|
||||
+ "^fdhisi,.*":
|
||||
+ description: Fuzhou Fuda Hisi Microelectronics Co., Ltd.
|
||||
"^feixin,.*":
|
||||
description: Shenzhen Feixin Photoelectic Co., Ltd
|
||||
"^feiyang,.*":
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From d05fd0dbca2f4e7233ca5c1fb9fc8ca5575d4dbc Mon Sep 17 00:00:00 2001
|
||||
From b367cb5a336587e37d6aeaad57359af4c9ed4d48 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Wed, 19 Jan 2022 06:45:06 +0000
|
||||
Subject: [PATCH 29/37] WIP: arm64: dts: meson: add UHS SDIO capabilities to
|
||||
Subject: [PATCH 34/54] WIP: arm64: dts: meson: add UHS SDIO capabilities to
|
||||
p212/p23x/q20x
|
||||
|
||||
Add UHS capabilities to the SDIO node to enable 100MHz speeds.
|
||||
@@ -1,159 +0,0 @@
|
||||
From 793c581ca351bfa08e185c3625ede56cc4cabf3f Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Thu, 12 Jun 2025 10:30:51 +0000
|
||||
Subject: [PATCH 34/37] WIP: dt-bindings: auxdisplay: add Titan Micro
|
||||
Electronics TM16XX
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add documentation for auxiliary displays based on TM16XX and compatible
|
||||
LED controllers.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
|
||||
---
|
||||
.../bindings/auxdisplay/tm16xx.yaml | 131 ++++++++++++++++++
|
||||
1 file changed, 131 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/auxdisplay/tm16xx.yaml
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/auxdisplay/tm16xx.yaml b/Documentation/devicetree/bindings/auxdisplay/tm16xx.yaml
|
||||
new file mode 100644
|
||||
index 000000000000..80b54572926c
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/auxdisplay/tm16xx.yaml
|
||||
@@ -0,0 +1,131 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/auxdisplay/tm16xx.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: TM16XX and Compatible Auxiliary Display Driver
|
||||
+
|
||||
+maintainers:
|
||||
+ - Jean-François Lessard <jefflessard3@gmail.com>
|
||||
+
|
||||
+description: |
|
||||
+ Bindings for auxiliary displays based on TM16XX and compatible LED controllers.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ enum:
|
||||
+ - titanmec,tm1618
|
||||
+ - titanmec,tm1620
|
||||
+ - titanmec,tm1628
|
||||
+ - titanmec,tm1650
|
||||
+ - fdhisi,fd620
|
||||
+ - fdhisi,fd628
|
||||
+ - fdhisi,fd650
|
||||
+ - fdhisi,fd6551
|
||||
+ - fdhisi,fd655
|
||||
+ - princeton,pt6964
|
||||
+ - hbs,hbs658
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ tm16xx,digits:
|
||||
+ description: Array of grid indexes for each digit
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
+ items:
|
||||
+ minimum: 0
|
||||
+ maximum: 7
|
||||
+ minItems: 1
|
||||
+ maxItems: 8
|
||||
+
|
||||
+ tm16xx,segment-mapping:
|
||||
+ description: Array specifying segment mapping (must be exactly 7 elements)
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
+ items:
|
||||
+ minimum: 0
|
||||
+ maximum: 7
|
||||
+ minItems: 7
|
||||
+ maxItems: 7
|
||||
+
|
||||
+ tm16xx,transposed:
|
||||
+ description: |
|
||||
+ Optional boolean flag indicating if the device output is transposed.
|
||||
+ If not present, the default value is false.
|
||||
+ $ref: /schemas/types.yaml#/definitions/flag
|
||||
+
|
||||
+ "#address-cells":
|
||||
+ const: 2
|
||||
+
|
||||
+ "#size-cells":
|
||||
+ const: 0
|
||||
+
|
||||
+patternProperties:
|
||||
+ "^led@[0-7],[0-7]$":
|
||||
+ $ref: /schemas/leds/common.yaml#
|
||||
+ properties:
|
||||
+ reg:
|
||||
+ description: Grid and segment indexes
|
||||
+ required:
|
||||
+ - reg
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+ - tm16xx,digits
|
||||
+ - tm16xx,segment-mapping
|
||||
+
|
||||
+additionalProperties: true
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ display_client: i2c {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ display@24 {
|
||||
+ compatible = "titanmec,tm1650";
|
||||
+ reg = <0x24>;
|
||||
+ tm16xx,digits = /bits/ 8 <0 1 2 3>;
|
||||
+ tm16xx,segment-mapping = /bits/ 8 <0 1 2 3 4 5 6>;
|
||||
+
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ led@4,0 {
|
||||
+ reg = <4 0>;
|
||||
+ function = "lan";
|
||||
+ };
|
||||
+
|
||||
+ led@4,1 {
|
||||
+ reg = <4 1>;
|
||||
+ function = "wlan";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ - |
|
||||
+ display_client: spi {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ display@0 {
|
||||
+ compatible = "titanmec,tm1628";
|
||||
+ reg = <0>;
|
||||
+ tm16xx,transposed;
|
||||
+ tm16xx,digits = /bits/ 8 <1 2 3 4>;
|
||||
+ tm16xx,segment-mapping = /bits/ 8 <0 1 2 3 4 5 6>;
|
||||
+
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ led@0,2 {
|
||||
+ reg = <0 2>;
|
||||
+ function = "usb";
|
||||
+ };
|
||||
+
|
||||
+ led@0,3 {
|
||||
+ reg = <0 3>;
|
||||
+ function = "power";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
From 536382633e9e399907fe06f34f426184965b5ab1 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Wed, 11 Jun 2025 11:23:44 +0000
|
||||
Subject: [PATCH 35/37] WIP: arm64: dts: meson-gxl-s905w-tx3-mini: support the
|
||||
fd628 display
|
||||
|
||||
The TX3-mini has an FD628 display. Add support using the tm166xx
|
||||
kernel driver and userspace tools [0].
|
||||
|
||||
[0] https://github.com/jefflessard/tm16xx-display
|
||||
|
||||
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
|
||||
---
|
||||
.../dts/amlogic/meson-gxl-s905w-tx3-mini.dts | 63 +++++++++++++++++++
|
||||
1 file changed, 63 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
|
||||
index 6705c2082a78..94cae3a59554 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
#include "meson-gxl-s905x.dtsi"
|
||||
#include "meson-gx-p23x-q20x.dtsi"
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/leds/common.h>
|
||||
|
||||
/ {
|
||||
compatible = "oranth,tx3-mini", "amlogic,s905w", "amlogic,meson-gxl";
|
||||
@@ -19,6 +21,67 @@ memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x0 0x0 0x40000000>; /* 1 GiB or 2 GiB */
|
||||
};
|
||||
+
|
||||
+ display_client: spi {
|
||||
+ compatible = "spi-gpio";
|
||||
+ sck-gpios = <&gpio 76 GPIO_ACTIVE_HIGH>;
|
||||
+ mosi-gpios = <&gpio 75 GPIO_ACTIVE_HIGH>;
|
||||
+ cs-gpios = <&gpio_ao 4 GPIO_ACTIVE_LOW>;
|
||||
+ num-chipselects = <1>;
|
||||
+
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ display@0 {
|
||||
+ compatible = "fdhisi,fd628";
|
||||
+ reg = <0x0>;
|
||||
+ spi-3wire;
|
||||
+ spi-lsb-first;
|
||||
+ spi-rx-delay-us = <1>;
|
||||
+ spi-max-frequency = <500000>;
|
||||
+
|
||||
+ tm16xx,digits = [03 02 01 00];
|
||||
+ tm16xx,segment-mapping = [03 04 05 00 01 02 06];
|
||||
+
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ led@4,0 {
|
||||
+ reg = <4 0>;
|
||||
+ function = LED_FUNCTION_ALARM;
|
||||
+ };
|
||||
+
|
||||
+ led@4,1 {
|
||||
+ reg = <4 1>;
|
||||
+ function = LED_FUNCTION_USB;
|
||||
+ };
|
||||
+
|
||||
+ led@4,2 {
|
||||
+ reg = <4 2>;
|
||||
+ function = "play";
|
||||
+ };
|
||||
+
|
||||
+ led@4,3 {
|
||||
+ reg = <4 3>;
|
||||
+ function = "pause";
|
||||
+ };
|
||||
+
|
||||
+ led@4,4 {
|
||||
+ reg = <4 4>;
|
||||
+ function = "colon";
|
||||
+ };
|
||||
+
|
||||
+ led@4,5 {
|
||||
+ reg = <4 5>;
|
||||
+ function = LED_FUNCTION_LAN;
|
||||
+ };
|
||||
+
|
||||
+ led@4,6 {
|
||||
+ reg = <4 6>;
|
||||
+ function = LED_FUNCTION_WLAN;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&ir {
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 595ae18972bfb55b20eecf724cf73d3c3b133910 Mon Sep 17 00:00:00 2001
|
||||
From b8baf3c9ff435223796c3c2c7191727486e61ed2 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Thu, 9 Feb 2023 09:59:58 +0000
|
||||
Subject: [PATCH 30/37] WIP: dt-bindings: arm: amlogic: add support for Tanix
|
||||
Subject: [PATCH 35/54] WIP: dt-bindings: arm: amlogic: add support for Tanix
|
||||
TX9 Pro
|
||||
|
||||
The Oranth Tanix TX9 Pro is an Android STB using the Amlogic S912 chip
|
||||
@@ -1,7 +1,7 @@
|
||||
From 08187f15dc8ca4b29e2b847b3c5ed0026191480e Mon Sep 17 00:00:00 2001
|
||||
From d112d904b1613118e5c2b9e0e9e874678de1f261 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Thu, 9 Feb 2023 10:01:14 +0000
|
||||
Subject: [PATCH 31/37] WIP: arm64: dts: meson: add initial device-tree for
|
||||
Subject: [PATCH 36/54] WIP: arm64: dts: meson: add initial device-tree for
|
||||
Tanix TX9 Pro
|
||||
|
||||
Oranth Tanix TX9 Pro is based on the Amlogic Q200 reference design with
|
||||
@@ -1,99 +0,0 @@
|
||||
From 6bf5753f848d4c9e66d5e55929b307715ee1d5c5 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Thu, 9 Feb 2023 10:11:39 +0000
|
||||
Subject: [PATCH 36/37] WIP: arm64: dts: meson-gxm-tx9-pro: support the fd628
|
||||
display
|
||||
|
||||
The TX9-Pro has an FD628 display. Add support using the tm166xx
|
||||
kernel driver and userspace tools [0].
|
||||
|
||||
[0] https://github.com/jefflessard/tm16xx-display
|
||||
|
||||
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
|
||||
---
|
||||
.../boot/dts/amlogic/meson-gxm-tx9-pro.dts | 62 +++++++++++++++++++
|
||||
1 file changed, 62 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts
|
||||
index 9a62176cfe5a..08603b035868 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "meson-gxm.dtsi"
|
||||
#include "meson-gx-p23x-q20x.dtsi"
|
||||
#include <dt-bindings/input/input.h>
|
||||
+#include <dt-bindings/leds/common.h>
|
||||
|
||||
/ {
|
||||
compatible = "oranth,tx9-pro", "amlogic,s912", "amlogic,meson-gxm";
|
||||
@@ -37,6 +38,67 @@ button {
|
||||
gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
+
|
||||
+ display_client: spi {
|
||||
+ compatible = "spi-gpio";
|
||||
+ sck-gpios = <&gpio 76 GPIO_ACTIVE_HIGH>;
|
||||
+ mosi-gpios = <&gpio 75 GPIO_ACTIVE_HIGH>;
|
||||
+ cs-gpios = <&gpio 53 GPIO_ACTIVE_LOW>;
|
||||
+ num-chipselects = <1>;
|
||||
+
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ display@0 {
|
||||
+ compatible = "fdhisi,fd628";
|
||||
+ reg = <0x0>;
|
||||
+ spi-3wire;
|
||||
+ spi-lsb-first;
|
||||
+ spi-rx-delay-us = <1>;
|
||||
+ spi-max-frequency = <500000>;
|
||||
+
|
||||
+ tm16xx,digits = [00 01 02 03];
|
||||
+ tm16xx,segment-mapping = [03 01 02 06 04 05 00];
|
||||
+
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ led@4,0 {
|
||||
+ reg = <4 0>;
|
||||
+ function = LED_FUNCTION_ALARM;
|
||||
+ };
|
||||
+
|
||||
+ led@4,1 {
|
||||
+ reg = <4 1>;
|
||||
+ function = LED_FUNCTION_USB;
|
||||
+ };
|
||||
+
|
||||
+ led@4,2 {
|
||||
+ reg = <4 2>;
|
||||
+ function = "play";
|
||||
+ };
|
||||
+
|
||||
+ led@4,3 {
|
||||
+ reg = <4 3>;
|
||||
+ function = "pause";
|
||||
+ };
|
||||
+
|
||||
+ led@4,4 {
|
||||
+ reg = <4 4>;
|
||||
+ function = "colon";
|
||||
+ };
|
||||
+
|
||||
+ led@4,5 {
|
||||
+ reg = <4 5>;
|
||||
+ function = LED_FUNCTION_LAN;
|
||||
+ };
|
||||
+
|
||||
+ led@4,6 {
|
||||
+ reg = <4 6>;
|
||||
+ function = LED_FUNCTION_WLAN;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
ðmac {
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
From 7f3cc57dc50d31414a284761cfb5372942229571 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Wed, 11 Jun 2025 11:47:31 +0000
|
||||
Subject: [PATCH 37/37] WIP: arm64: dts: meson-g12a-x96-max: support the fd628
|
||||
display
|
||||
|
||||
The X96-Max has an FD628 display. Add support using the tm166xx
|
||||
kernel driver and userspace tools [0].
|
||||
|
||||
[0] https://github.com/jefflessard/tm16xx-display
|
||||
|
||||
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
|
||||
---
|
||||
.../boot/dts/amlogic/meson-g12a-x96-max.dts | 63 +++++++++++++++++++
|
||||
1 file changed, 63 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
|
||||
index 5ab460a3e637..879276d6f6e9 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "meson-g12a.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/gpio/meson-g12a-gpio.h>
|
||||
#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
|
||||
|
||||
@@ -54,6 +55,68 @@ hdmi_connector_in: endpoint {
|
||||
};
|
||||
};
|
||||
|
||||
+ display_client: spi {
|
||||
+ compatible = "spi-gpio";
|
||||
+ sck-gpios = <&gpio 64 GPIO_ACTIVE_HIGH>;
|
||||
+ mosi-gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
|
||||
+ cs-gpios = <&gpio_ao 10 GPIO_ACTIVE_LOW>;
|
||||
+ num-chipselects = <1>;
|
||||
+
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ display@0 {
|
||||
+ compatible = "fdhisi,fd628";
|
||||
+ reg = <0x0>;
|
||||
+ spi-3wire;
|
||||
+ spi-lsb-first;
|
||||
+ spi-rx-delay-us = <1>;
|
||||
+ spi-max-frequency = <500000>;
|
||||
+
|
||||
+ tm16xx,transposed;
|
||||
+ tm16xx,digits = [00 01 02 03];
|
||||
+ tm16xx,segment-mapping = [00 01 02 03 04 05 06];
|
||||
+
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ led@4,0 {
|
||||
+ reg = <4 0>;
|
||||
+ function = "apps";
|
||||
+ };
|
||||
+
|
||||
+ led@4,1 {
|
||||
+ reg = <4 1>;
|
||||
+ function = "setup";
|
||||
+ };
|
||||
+
|
||||
+ led@4,2 {
|
||||
+ reg = <4 2>;
|
||||
+ function = LED_FUNCTION_USB;
|
||||
+ };
|
||||
+
|
||||
+ led@4,3 {
|
||||
+ reg = <4 3>;
|
||||
+ function = LED_FUNCTION_SD;
|
||||
+ };
|
||||
+
|
||||
+ led@4,4 {
|
||||
+ reg = <4 4>;
|
||||
+ function = "colon";
|
||||
+ };
|
||||
+
|
||||
+ led@4,5 {
|
||||
+ reg = <4 5>;
|
||||
+ function = "hdmi";
|
||||
+ };
|
||||
+
|
||||
+ led@4,6 {
|
||||
+ reg = <4 6>;
|
||||
+ function = "video";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
emmc_pwrseq: emmc-pwrseq {
|
||||
compatible = "mmc-pwrseq-emmc";
|
||||
reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
From 151262abde300e5b8c417f02b75e6c27cd79805c Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Wed, 3 Sep 2025 04:49:02 +0000
|
||||
Subject: [PATCH 37/54] WIP: net: phy: icplus: add support for IP1001 variants
|
||||
|
||||
Experimental patch that:
|
||||
|
||||
- Adds #define IP1001_PHY_ID_ALT 0x02430d91
|
||||
- Adds #define IP100C_PHY_ID 0x02430d98
|
||||
- Adds variants to the icplus_driver[] array
|
||||
- Adds variants to the MDIO device table
|
||||
|
||||
The IP1001 ALT device uses the same init/config as the existing device,
|
||||
while the IP1001C has some init differences.
|
||||
|
||||
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
|
||||
---
|
||||
drivers/net/phy/icplus.c | 69 +++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 68 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
|
||||
index c0c4f19cfb6a..4b5f593e0943 100644
|
||||
--- a/drivers/net/phy/icplus.c
|
||||
+++ b/drivers/net/phy/icplus.c
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <asm/irq.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
-MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IC1001 PHY drivers");
|
||||
+MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IP1001/IP1001C PHY drivers");
|
||||
MODULE_AUTHOR("Michael Barkowski");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -64,6 +64,9 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
#define IP175C_PHY_ID 0x02430d80
|
||||
#define IP1001_PHY_ID 0x02430d90
|
||||
+#define IP1001_PHY_ID_ALT 0x02430d91 // Additional identifier for IP1001
|
||||
+#define IP1001C_PHY_ID 0x02430d98 // New: IP1001C identifier
|
||||
+
|
||||
#define IP101A_PHY_ID 0x02430c54
|
||||
|
||||
/* The 32-pin IP101GR package can re-configure the mode of the RXER/INTR_32 pin
|
||||
@@ -182,6 +185,52 @@ static int ip1001_config_init(struct phy_device *phydev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* IP1001C specific config_init */
|
||||
+static int ip1001c_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ int val, ret;
|
||||
+
|
||||
+ /* Enable Auto Power Saving mode (same as IP1001) */
|
||||
+ val = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2);
|
||||
+ if (val < 0)
|
||||
+ return val;
|
||||
+ val |= IP1001_APS_ON;
|
||||
+ ret = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, val);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* RGMII delay settings, similar to IP1001, if required for IP1001C */
|
||||
+ if (phy_interface_is_rgmii(phydev)) {
|
||||
+ val = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
|
||||
+ if (val < 0)
|
||||
+ return val;
|
||||
+
|
||||
+ val &= ~(IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
|
||||
+
|
||||
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
|
||||
+ val |= (IP1001_RXPHASE_SEL | IP1001_TXPHASE_SEL);
|
||||
+ else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
|
||||
+ val |= IP1001_RXPHASE_SEL;
|
||||
+ else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
|
||||
+ val |= IP1001_TXPHASE_SEL;
|
||||
+
|
||||
+ ret = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, val);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* IP1001C specific workaround: force 1000M/Master/Full-Duplex */
|
||||
+ ret = phy_write(phydev, MII_BMCR, 0x0140); /* Full Duplex */
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = phy_write(phydev, MII_CTRL1000, 0x1800); /* 1000M Master */
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int ip175c_read_status(struct phy_device *phydev)
|
||||
{
|
||||
if (phydev->mdio.addr == 4) /* WAN port */
|
||||
@@ -590,6 +639,22 @@ static struct phy_driver icplus_driver[] = {
|
||||
.soft_reset = genphy_soft_reset,
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
+}, {
|
||||
+ PHY_ID_MATCH_MODEL(IP1001_PHY_ID_ALT),
|
||||
+ .name = "ICPlus IP1001",
|
||||
+ /* PHY_GBIT_FEATURES */
|
||||
+ .config_init = ip1001_config_init,
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
+}, {
|
||||
+ PHY_ID_MATCH_MODEL(IP1001C_PHY_ID),
|
||||
+ .name = "ICPlus IP1001C",
|
||||
+ /* PHY_GBIT_FEATURES */
|
||||
+ .config_init = ip1001c_config_init,
|
||||
+ .soft_reset = genphy_soft_reset,
|
||||
+ .suspend = genphy_suspend,
|
||||
+ .resume = genphy_resume,
|
||||
}, {
|
||||
.name = "ICPlus IP101A",
|
||||
.match_phy_device = ip101a_match_phy_device,
|
||||
@@ -628,6 +693,8 @@ module_phy_driver(icplus_driver);
|
||||
static const struct mdio_device_id __maybe_unused icplus_tbl[] = {
|
||||
{ PHY_ID_MATCH_MODEL(IP175C_PHY_ID) },
|
||||
{ PHY_ID_MATCH_MODEL(IP1001_PHY_ID) },
|
||||
+ { PHY_ID_MATCH_MODEL(IP1001_PHY_ID_ALT) },
|
||||
+ { PHY_ID_MATCH_MODEL(IP1001C_PHY_ID) },
|
||||
{ PHY_ID_MATCH_EXACT(IP101A_PHY_ID) },
|
||||
{ }
|
||||
};
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From 5ddfb27c0b310e3431336250c2ccf2fda3d8ddb1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Mon, 1 Sep 2025 12:16:39 -0400
|
||||
Subject: [PATCH 38/54] TEST: device property: Add scoped fwnode child node
|
||||
iterators
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add scoped versions of fwnode child node iterators that automatically
|
||||
handle reference counting cleanup using the __free() attribute:
|
||||
|
||||
- fwnode_for_each_child_node_scoped()
|
||||
- fwnode_for_each_available_child_node_scoped()
|
||||
|
||||
These macros follow the same pattern as existing scoped iterators in the
|
||||
kernel, ensuring fwnode references are automatically released when the
|
||||
iterator variable goes out of scope. This prevents resource leaks and
|
||||
eliminates the need for manual cleanup in error paths.
|
||||
|
||||
The implementation mirrors the non-scoped variants but uses
|
||||
__free(fwnode_handle) for automatic resource management, providing a
|
||||
safer and more convenient interface for drivers iterating over firmware
|
||||
node children.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
include/linux/property.h | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/include/linux/property.h b/include/linux/property.h
|
||||
index f718dd4789e5..8d119ee9f04a 100644
|
||||
--- a/include/linux/property.h
|
||||
+++ b/include/linux/property.h
|
||||
@@ -175,6 +175,16 @@ struct fwnode_handle *fwnode_get_next_available_child_node(
|
||||
for (child = fwnode_get_next_available_child_node(fwnode, NULL); child;\
|
||||
child = fwnode_get_next_available_child_node(fwnode, child))
|
||||
|
||||
+#define fwnode_for_each_child_node_scoped(fwnode, child) \
|
||||
+ for (struct fwnode_handle *child __free(fwnode_handle) = \
|
||||
+ fwnode_get_next_child_node(fwnode, NULL); \
|
||||
+ child; child = fwnode_get_next_child_node(fwnode, child))
|
||||
+
|
||||
+#define fwnode_for_each_available_child_node_scoped(fwnode, child) \
|
||||
+ for (struct fwnode_handle *child __free(fwnode_handle) = \
|
||||
+ fwnode_get_next_available_child_node(fwnode, NULL); \
|
||||
+ child; child = fwnode_get_next_available_child_node(fwnode, child))
|
||||
+
|
||||
struct fwnode_handle *device_get_next_child_node(const struct device *dev,
|
||||
struct fwnode_handle *child);
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
From cf44b702a20d1cbd422d5116e3fe164852ca92f1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Mon, 1 Sep 2025 12:18:40 -0400
|
||||
Subject: [PATCH 39/54] TEST: i2c: core: Use
|
||||
fwnode_for_each_child_node_scoped()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Replace the manual __free(fwnode_handle) iterator declaration with the
|
||||
new scoped iterator macro for cleaner, less error-prone code.
|
||||
|
||||
This eliminates the need for explicit iterator variable declaration with
|
||||
the cleanup attribute, making the code more consistent with other scoped
|
||||
iterator usage patterns in the kernel.
|
||||
|
||||
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
drivers/i2c/i2c-core-slave.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/i2c-core-slave.c b/drivers/i2c/i2c-core-slave.c
|
||||
index 7ee6b992b835..02ca55c2246b 100644
|
||||
--- a/drivers/i2c/i2c-core-slave.c
|
||||
+++ b/drivers/i2c/i2c-core-slave.c
|
||||
@@ -112,10 +112,9 @@ bool i2c_detect_slave_mode(struct device *dev)
|
||||
struct fwnode_handle *fwnode = dev_fwnode(dev);
|
||||
|
||||
if (is_of_node(fwnode)) {
|
||||
- struct fwnode_handle *child __free(fwnode_handle) = NULL;
|
||||
u32 reg;
|
||||
|
||||
- fwnode_for_each_child_node(fwnode, child) {
|
||||
+ fwnode_for_each_child_node_scoped(fwnode, child) {
|
||||
fwnode_property_read_u32(child, "reg", ®);
|
||||
if (reg & I2C_OWN_SLAVE_ADDRESS)
|
||||
return true;
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
From cd95e8fd35c9fb37de5723a464d5fcc831c58ec1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Sat, 30 Aug 2025 20:31:38 -0400
|
||||
Subject: [PATCH 40/54] TEST: auxdisplay: linedisp: encapsulate container_of
|
||||
usage within to_linedisp
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Replace direct container_of() calls with a to_linedisp() helper function
|
||||
throughout the line-display auxdisplay library module. This abstraction
|
||||
prepares for upcoming dual-mode support where linedisp context retrieval
|
||||
will need to handle both dedicated child devices and attached parent
|
||||
auxdisplay devices.
|
||||
|
||||
No functional changes in this patch.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
drivers/auxdisplay/line-display.c | 21 +++++++++++++--------
|
||||
1 file changed, 13 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c
|
||||
index 8590a4cd21e0..e44341b1ea22 100644
|
||||
--- a/drivers/auxdisplay/line-display.c
|
||||
+++ b/drivers/auxdisplay/line-display.c
|
||||
@@ -31,6 +31,11 @@
|
||||
|
||||
#define DEFAULT_SCROLL_RATE (HZ / 2)
|
||||
|
||||
+static struct linedisp *to_linedisp(struct device *dev)
|
||||
+{
|
||||
+ return container_of(dev, struct linedisp, dev);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* linedisp_scroll() - scroll the display by a character
|
||||
* @t: really a pointer to the private data structure
|
||||
@@ -133,7 +138,7 @@ static int linedisp_display(struct linedisp *linedisp, const char *msg,
|
||||
static ssize_t message_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
- struct linedisp *linedisp = container_of(dev, struct linedisp, dev);
|
||||
+ struct linedisp *linedisp = to_linedisp(dev);
|
||||
|
||||
return sysfs_emit(buf, "%s\n", linedisp->message);
|
||||
}
|
||||
@@ -152,7 +157,7 @@ static ssize_t message_show(struct device *dev, struct device_attribute *attr,
|
||||
static ssize_t message_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
- struct linedisp *linedisp = container_of(dev, struct linedisp, dev);
|
||||
+ struct linedisp *linedisp = to_linedisp(dev);
|
||||
int err;
|
||||
|
||||
err = linedisp_display(linedisp, buf, count);
|
||||
@@ -164,7 +169,7 @@ static DEVICE_ATTR_RW(message);
|
||||
static ssize_t scroll_step_ms_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
- struct linedisp *linedisp = container_of(dev, struct linedisp, dev);
|
||||
+ struct linedisp *linedisp = to_linedisp(dev);
|
||||
|
||||
return sysfs_emit(buf, "%u\n", jiffies_to_msecs(linedisp->scroll_rate));
|
||||
}
|
||||
@@ -173,7 +178,7 @@ static ssize_t scroll_step_ms_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
- struct linedisp *linedisp = container_of(dev, struct linedisp, dev);
|
||||
+ struct linedisp *linedisp = to_linedisp(dev);
|
||||
unsigned int ms;
|
||||
int err;
|
||||
|
||||
@@ -195,7 +200,7 @@ static DEVICE_ATTR_RW(scroll_step_ms);
|
||||
|
||||
static ssize_t map_seg_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
- struct linedisp *linedisp = container_of(dev, struct linedisp, dev);
|
||||
+ struct linedisp *linedisp = to_linedisp(dev);
|
||||
struct linedisp_map *map = linedisp->map;
|
||||
|
||||
memcpy(buf, &map->map, map->size);
|
||||
@@ -205,7 +210,7 @@ static ssize_t map_seg_show(struct device *dev, struct device_attribute *attr, c
|
||||
static ssize_t map_seg_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
- struct linedisp *linedisp = container_of(dev, struct linedisp, dev);
|
||||
+ struct linedisp *linedisp = to_linedisp(dev);
|
||||
struct linedisp_map *map = linedisp->map;
|
||||
|
||||
if (count != map->size)
|
||||
@@ -232,7 +237,7 @@ static struct attribute *linedisp_attrs[] = {
|
||||
static umode_t linedisp_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
|
||||
{
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
- struct linedisp *linedisp = container_of(dev, struct linedisp, dev);
|
||||
+ struct linedisp *linedisp = to_linedisp(dev);
|
||||
struct linedisp_map *map = linedisp->map;
|
||||
umode_t mode = attr->mode;
|
||||
|
||||
@@ -263,7 +268,7 @@ static DEFINE_IDA(linedisp_id);
|
||||
|
||||
static void linedisp_release(struct device *dev)
|
||||
{
|
||||
- struct linedisp *linedisp = container_of(dev, struct linedisp, dev);
|
||||
+ struct linedisp *linedisp = to_linedisp(dev);
|
||||
|
||||
kfree(linedisp->map);
|
||||
kfree(linedisp->message);
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
From a03fdbc61651abaf17e48cd4a867e8858685078d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Sun, 31 Aug 2025 13:53:01 -0400
|
||||
Subject: [PATCH 41/54] TEST: auxdisplay: linedisp: display static message when
|
||||
length <= display size
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Currently, when a message shorter than the display size is written, the
|
||||
content wraps around (e.g., "123" on a 4-digit display shows "1231")
|
||||
without scrolling, which is confusing and unintuitive.
|
||||
|
||||
Change behavior to display short messages statically with space padding
|
||||
(e.g. "123 ") while only scrolling messages longer than the display width.
|
||||
This provides more natural behavior that aligns with user expectations
|
||||
and current linedisp_display() kernel-doc.
|
||||
|
||||
The scroll logic is also consolidated into a helper function for clarity.
|
||||
|
||||
No API changes are introduced.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
drivers/auxdisplay/line-display.c | 29 +++++++++++++++++++++--------
|
||||
1 file changed, 21 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c
|
||||
index e44341b1ea22..ea23c43bb7b2 100644
|
||||
--- a/drivers/auxdisplay/line-display.c
|
||||
+++ b/drivers/auxdisplay/line-display.c
|
||||
@@ -36,6 +36,11 @@ static struct linedisp *to_linedisp(struct device *dev)
|
||||
return container_of(dev, struct linedisp, dev);
|
||||
}
|
||||
|
||||
+static inline bool should_scroll(struct linedisp *linedisp)
|
||||
+{
|
||||
+ return linedisp->message_len > linedisp->num_chars && linedisp->scroll_rate;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* linedisp_scroll() - scroll the display by a character
|
||||
* @t: really a pointer to the private data structure
|
||||
@@ -67,7 +72,7 @@ static void linedisp_scroll(struct timer_list *t)
|
||||
linedisp->scroll_pos %= linedisp->message_len;
|
||||
|
||||
/* rearm the timer */
|
||||
- if (linedisp->message_len > num_chars && linedisp->scroll_rate)
|
||||
+ if (should_scroll(linedisp))
|
||||
mod_timer(&linedisp->timer, jiffies + linedisp->scroll_rate);
|
||||
}
|
||||
|
||||
@@ -118,8 +123,16 @@ static int linedisp_display(struct linedisp *linedisp, const char *msg,
|
||||
linedisp->message_len = count;
|
||||
linedisp->scroll_pos = 0;
|
||||
|
||||
- /* update the display */
|
||||
- linedisp_scroll(&linedisp->timer);
|
||||
+ if (should_scroll(linedisp)) {
|
||||
+ /* display scrolling message */
|
||||
+ linedisp_scroll(&linedisp->timer);
|
||||
+ } else {
|
||||
+ /* display static message */
|
||||
+ memset(linedisp->buf, ' ', linedisp->num_chars);
|
||||
+ memcpy(linedisp->buf, linedisp->message,
|
||||
+ umin(linedisp->num_chars, linedisp->message_len));
|
||||
+ linedisp->ops->update(linedisp);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -186,12 +199,12 @@ static ssize_t scroll_step_ms_store(struct device *dev,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ timer_delete_sync(&linedisp->timer);
|
||||
+
|
||||
linedisp->scroll_rate = msecs_to_jiffies(ms);
|
||||
- if (linedisp->message && linedisp->message_len > linedisp->num_chars) {
|
||||
- timer_delete_sync(&linedisp->timer);
|
||||
- if (linedisp->scroll_rate)
|
||||
- linedisp_scroll(&linedisp->timer);
|
||||
- }
|
||||
+
|
||||
+ if (should_scroll(linedisp))
|
||||
+ linedisp_scroll(&linedisp->timer);
|
||||
|
||||
return count;
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From 9101338af83f9e74bad4163ad4d6569cb812699f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Sat, 30 Aug 2025 20:35:34 -0400
|
||||
Subject: [PATCH 42/54] TEST: auxdisplay: linedisp: add num_chars sysfs
|
||||
attribute
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add a read-only 'num_chars' sysfs attribute to report display digit count.
|
||||
|
||||
The num_chars attribute provides essential capability information to
|
||||
userspace applications that need to know display dimensions before writing
|
||||
messages, complementing the existing message and scroll controls.
|
||||
|
||||
No functional changes to existing behavior.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
drivers/auxdisplay/line-display.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c
|
||||
index ea23c43bb7b2..abeed8812088 100644
|
||||
--- a/drivers/auxdisplay/line-display.c
|
||||
+++ b/drivers/auxdisplay/line-display.c
|
||||
@@ -211,6 +211,16 @@ static ssize_t scroll_step_ms_store(struct device *dev,
|
||||
|
||||
static DEVICE_ATTR_RW(scroll_step_ms);
|
||||
|
||||
+static ssize_t num_chars_show(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct linedisp *linedisp = to_linedisp(dev);
|
||||
+
|
||||
+ return sysfs_emit(buf, "%u\n", linedisp->num_chars);
|
||||
+}
|
||||
+
|
||||
+static DEVICE_ATTR_RO(num_chars);
|
||||
+
|
||||
static ssize_t map_seg_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct linedisp *linedisp = to_linedisp(dev);
|
||||
@@ -242,6 +252,7 @@ static DEVICE_ATTR(map_seg14, 0644, map_seg_show, map_seg_store);
|
||||
static struct attribute *linedisp_attrs[] = {
|
||||
&dev_attr_message.attr,
|
||||
&dev_attr_scroll_step_ms.attr,
|
||||
+ &dev_attr_num_chars.attr,
|
||||
&dev_attr_map_seg7.attr,
|
||||
&dev_attr_map_seg14.attr,
|
||||
NULL
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
From 15c9ea76e000b860749d9c27e0d374cd0bcbe40a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Sat, 30 Aug 2025 20:41:39 -0400
|
||||
Subject: [PATCH 43/54] TEST: auxdisplay: linedisp: support attribute
|
||||
attachment to auxdisplay devices
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Enable linedisp library integration into existing kernel devices (like LED
|
||||
class) to provide a uniform 7-segment userspace API without creating
|
||||
separate child devices, meeting the consistent interface while maintaining
|
||||
coherent device hierarchies.
|
||||
|
||||
This allows uniform 7-segment API across all drivers while solving device
|
||||
proliferation and fragmented userspace interfaces.
|
||||
|
||||
The provided attributes appear in two locations depending on usage:
|
||||
1. On linedisp.N child devices (legacy linedisp_register())
|
||||
2. On the parent auxdisplay device (new linedisp_attach())
|
||||
Functionality is identical in both modes.
|
||||
|
||||
Existing consumers of linedisp_register() are unaffected. The new API
|
||||
enables drivers like TM16XX to integrate 7-segment display functionality
|
||||
seamlessly within their LED class device hierarchy.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
drivers/auxdisplay/line-display.c | 160 +++++++++++++++++++++++++++++-
|
||||
drivers/auxdisplay/line-display.h | 4 +
|
||||
2 files changed, 161 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c
|
||||
index abeed8812088..1176d46f0b24 100644
|
||||
--- a/drivers/auxdisplay/line-display.c
|
||||
+++ b/drivers/auxdisplay/line-display.c
|
||||
@@ -6,20 +6,23 @@
|
||||
* Author: Paul Burton <paul.burton@mips.com>
|
||||
*
|
||||
* Copyright (C) 2021 Glider bv
|
||||
+ * Copyright (C) 2025 Jean-François Lessard
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_PANEL_BOOT_MESSAGE
|
||||
#include <generated/utsrelease.h>
|
||||
#endif
|
||||
|
||||
-#include <linux/container_of.h>
|
||||
+#include <linux/cleanup.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/kstrtox.h>
|
||||
+#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/spinlock.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/timer.h>
|
||||
@@ -31,9 +34,72 @@
|
||||
|
||||
#define DEFAULT_SCROLL_RATE (HZ / 2)
|
||||
|
||||
+struct linedisp_attachment {
|
||||
+ struct list_head list;
|
||||
+ struct device *device;
|
||||
+ struct linedisp *linedisp;
|
||||
+ bool owns_device; /* true for child device mode, false for attached mode */
|
||||
+};
|
||||
+
|
||||
+static LIST_HEAD(linedisp_attachments);
|
||||
+static DEFINE_SPINLOCK(linedisp_attachments_lock);
|
||||
+
|
||||
+static int create_attachment(struct device *dev, struct linedisp *linedisp, bool owns_device)
|
||||
+{
|
||||
+ struct linedisp_attachment *attachment;
|
||||
+
|
||||
+ attachment = kzalloc(sizeof(*attachment), GFP_KERNEL);
|
||||
+ if (!attachment)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ attachment->device = dev;
|
||||
+ attachment->linedisp = linedisp;
|
||||
+ attachment->owns_device = owns_device;
|
||||
+
|
||||
+ guard(spinlock)(&linedisp_attachments_lock);
|
||||
+ list_add(&attachment->list, &linedisp_attachments);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct linedisp *delete_attachment(struct device *dev, bool owns_device)
|
||||
+{
|
||||
+ struct linedisp_attachment *attachment;
|
||||
+ struct linedisp *linedisp;
|
||||
+
|
||||
+ guard(spinlock)(&linedisp_attachments_lock);
|
||||
+
|
||||
+ list_for_each_entry(attachment, &linedisp_attachments, list) {
|
||||
+ if (attachment->device == dev &&
|
||||
+ attachment->owns_device == owns_device)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (list_entry_is_head(attachment, &linedisp_attachments, list))
|
||||
+ return NULL;
|
||||
+
|
||||
+ linedisp = attachment->linedisp;
|
||||
+ list_del(&attachment->list);
|
||||
+ kfree(attachment);
|
||||
+
|
||||
+ return linedisp;
|
||||
+}
|
||||
+
|
||||
static struct linedisp *to_linedisp(struct device *dev)
|
||||
{
|
||||
- return container_of(dev, struct linedisp, dev);
|
||||
+ struct linedisp_attachment *attachment;
|
||||
+
|
||||
+ guard(spinlock)(&linedisp_attachments_lock);
|
||||
+
|
||||
+ list_for_each_entry(attachment, &linedisp_attachments, list) {
|
||||
+ if (attachment->device == dev)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (list_entry_is_head(attachment, &linedisp_attachments, list))
|
||||
+ return NULL;
|
||||
+
|
||||
+ return attachment->linedisp;
|
||||
}
|
||||
|
||||
static inline bool should_scroll(struct linedisp *linedisp)
|
||||
@@ -349,6 +415,87 @@ static int linedisp_init_map(struct linedisp *linedisp)
|
||||
#define LINEDISP_INIT_TEXT "Linux " UTS_RELEASE " "
|
||||
#endif
|
||||
|
||||
+/**
|
||||
+ * linedisp_attach - attach a character line display
|
||||
+ * @linedisp: pointer to character line display structure
|
||||
+ * @dev: pointer of the device to attach to
|
||||
+ * @num_chars: the number of characters that can be displayed
|
||||
+ * @ops: character line display operations
|
||||
+ *
|
||||
+ * Return: zero on success, else a negative error code.
|
||||
+ */
|
||||
+int linedisp_attach(struct linedisp *linedisp, struct device *dev,
|
||||
+ unsigned int num_chars, const struct linedisp_ops *ops)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ memset(linedisp, 0, sizeof(*linedisp));
|
||||
+ linedisp->ops = ops;
|
||||
+ linedisp->num_chars = num_chars;
|
||||
+ linedisp->scroll_rate = DEFAULT_SCROLL_RATE;
|
||||
+
|
||||
+ linedisp->buf = kzalloc(linedisp->num_chars, GFP_KERNEL);
|
||||
+ if (!linedisp->buf)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* initialise a character mapping, if required */
|
||||
+ err = linedisp_init_map(linedisp);
|
||||
+ if (err)
|
||||
+ goto out_free_buf;
|
||||
+
|
||||
+ /* initialise a timer for scrolling the message */
|
||||
+ timer_setup(&linedisp->timer, linedisp_scroll, 0);
|
||||
+
|
||||
+ err = create_attachment(dev, linedisp, false);
|
||||
+ if (err)
|
||||
+ goto out_del_timer;
|
||||
+
|
||||
+ /* add attribute groups to target device */
|
||||
+ err = device_add_groups(dev, linedisp_groups);
|
||||
+ if (err)
|
||||
+ goto out_del_attach;
|
||||
+
|
||||
+ /* display a default message */
|
||||
+ err = linedisp_display(linedisp, LINEDISP_INIT_TEXT, -1);
|
||||
+ if (err)
|
||||
+ goto out_rem_groups;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+out_rem_groups:
|
||||
+ device_remove_groups(dev, linedisp_groups);
|
||||
+out_del_attach:
|
||||
+ delete_attachment(dev, false);
|
||||
+out_del_timer:
|
||||
+ timer_delete_sync(&linedisp->timer);
|
||||
+out_free_buf:
|
||||
+ kfree(linedisp->buf);
|
||||
+ return err;
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(linedisp_attach, "LINEDISP");
|
||||
+
|
||||
+/**
|
||||
+ * linedisp_detach - detach a character line display
|
||||
+ * @dev: pointer of the device to detach from, that was previously
|
||||
+ * attached with linedisp_attach()
|
||||
+ */
|
||||
+void linedisp_detach(struct device *dev)
|
||||
+{
|
||||
+ struct linedisp *linedisp = delete_attachment(dev, false);
|
||||
+
|
||||
+ if (!linedisp)
|
||||
+ return;
|
||||
+
|
||||
+ timer_delete_sync(&linedisp->timer);
|
||||
+
|
||||
+ device_remove_groups(dev, linedisp_groups);
|
||||
+
|
||||
+ kfree(linedisp->map);
|
||||
+ kfree(linedisp->message);
|
||||
+ kfree(linedisp->buf);
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(linedisp_detach, "LINEDISP");
|
||||
+
|
||||
/**
|
||||
* linedisp_register - register a character line display
|
||||
* @linedisp: pointer to character line display structure
|
||||
@@ -391,10 +538,14 @@ int linedisp_register(struct linedisp *linedisp, struct device *parent,
|
||||
/* initialise a timer for scrolling the message */
|
||||
timer_setup(&linedisp->timer, linedisp_scroll, 0);
|
||||
|
||||
- err = device_add(&linedisp->dev);
|
||||
+ err = create_attachment(&linedisp->dev, linedisp, true);
|
||||
if (err)
|
||||
goto out_del_timer;
|
||||
|
||||
+ err = device_add(&linedisp->dev);
|
||||
+ if (err)
|
||||
+ goto out_del_attach;
|
||||
+
|
||||
/* display a default message */
|
||||
err = linedisp_display(linedisp, LINEDISP_INIT_TEXT, -1);
|
||||
if (err)
|
||||
@@ -404,6 +555,8 @@ int linedisp_register(struct linedisp *linedisp, struct device *parent,
|
||||
|
||||
out_del_dev:
|
||||
device_del(&linedisp->dev);
|
||||
+out_del_attach:
|
||||
+ delete_attachment(&linedisp->dev, true);
|
||||
out_del_timer:
|
||||
timer_delete_sync(&linedisp->timer);
|
||||
out_put_device:
|
||||
@@ -420,6 +573,7 @@ EXPORT_SYMBOL_NS_GPL(linedisp_register, "LINEDISP");
|
||||
void linedisp_unregister(struct linedisp *linedisp)
|
||||
{
|
||||
device_del(&linedisp->dev);
|
||||
+ delete_attachment(&linedisp->dev, true);
|
||||
timer_delete_sync(&linedisp->timer);
|
||||
put_device(&linedisp->dev);
|
||||
}
|
||||
diff --git a/drivers/auxdisplay/line-display.h b/drivers/auxdisplay/line-display.h
|
||||
index 4348d7a2f69a..36853b639711 100644
|
||||
--- a/drivers/auxdisplay/line-display.h
|
||||
+++ b/drivers/auxdisplay/line-display.h
|
||||
@@ -6,6 +6,7 @@
|
||||
* Author: Paul Burton <paul.burton@mips.com>
|
||||
*
|
||||
* Copyright (C) 2021 Glider bv
|
||||
+ * Copyright (C) 2025 Jean-François Lessard
|
||||
*/
|
||||
|
||||
#ifndef _LINEDISP_H
|
||||
@@ -81,6 +82,9 @@ struct linedisp {
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
+int linedisp_attach(struct linedisp *linedisp, struct device *dev,
|
||||
+ unsigned int num_chars, const struct linedisp_ops *ops);
|
||||
+void linedisp_detach(struct device *dev);
|
||||
int linedisp_register(struct linedisp *linedisp, struct device *parent,
|
||||
unsigned int num_chars, const struct linedisp_ops *ops);
|
||||
void linedisp_unregister(struct linedisp *linedisp);
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
From 6a205b4070ad6e129f80087d02baf0c7afd4b7e1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Sun, 31 Aug 2025 00:23:51 -0400
|
||||
Subject: [PATCH 44/54] TEST: docs: ABI: auxdisplay: document linedisp library
|
||||
sysfs attributes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add ABI documentation for sysfs attributes provided by the line-display
|
||||
auxdisplay library module. These attributes enable text message display and
|
||||
configuration on character-based auxdisplay devices.
|
||||
|
||||
Documents previously undocumented attributes:
|
||||
- message, scroll_step_ms (introduced in v5.16)
|
||||
- map_seg7, map_seg14 (introduced in v6.9)
|
||||
|
||||
Documents newly added attribute:
|
||||
- num_chars (targeted for v6.18)
|
||||
|
||||
The line-display library is used by multiple auxdisplay drivers and
|
||||
can expose these attributes either on linedisp.N child devices or
|
||||
directly on parent auxdisplay devices.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
.../ABI/testing/sysfs-auxdisplay-linedisp | 90 +++++++++++++++++++
|
||||
1 file changed, 90 insertions(+)
|
||||
create mode 100644 Documentation/ABI/testing/sysfs-auxdisplay-linedisp
|
||||
|
||||
diff --git a/Documentation/ABI/testing/sysfs-auxdisplay-linedisp b/Documentation/ABI/testing/sysfs-auxdisplay-linedisp
|
||||
new file mode 100644
|
||||
index 000000000000..63c47f19275e
|
||||
--- /dev/null
|
||||
+++ b/Documentation/ABI/testing/sysfs-auxdisplay-linedisp
|
||||
@@ -0,0 +1,90 @@
|
||||
+What: /sys/.../message
|
||||
+Date: October 2021
|
||||
+KernelVersion: 5.16
|
||||
+Description:
|
||||
+ Controls the text message displayed on character line displays.
|
||||
+
|
||||
+ Reading returns the current message with a trailing newline.
|
||||
+ Writing updates the displayed message. Messages longer than the
|
||||
+ display width will automatically scroll. Trailing newlines in
|
||||
+ input are automatically trimmed.
|
||||
+
|
||||
+ Writing an empty string clears the display.
|
||||
+
|
||||
+ Example:
|
||||
+ echo "Hello World" > message
|
||||
+ cat message # Returns "Hello World\n"
|
||||
+
|
||||
+What: /sys/.../scroll_step_ms
|
||||
+Date: October 2021
|
||||
+KernelVersion: 5.16
|
||||
+Description:
|
||||
+ Controls the scrolling speed for messages longer than the display
|
||||
+ width, specified in milliseconds per scroll step.
|
||||
+
|
||||
+ Setting to 0 disables scrolling. Default is 500ms.
|
||||
+
|
||||
+ Example:
|
||||
+ echo "250" > scroll_step_ms # 4Hz scrolling
|
||||
+ cat scroll_step_ms # Returns "250\n"
|
||||
+
|
||||
+What: /sys/.../num_chars
|
||||
+Date: November 2025
|
||||
+KernelVersion: 6.18
|
||||
+Contact: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
+Description:
|
||||
+ Read-only attribute showing the character width capacity of
|
||||
+ the line display device. Messages longer than this will scroll.
|
||||
+
|
||||
+ Example:
|
||||
+ cat num_chars # Returns "16\n" for 16-char display
|
||||
+
|
||||
+What: /sys/.../map_seg7
|
||||
+Date: January 2024
|
||||
+KernelVersion: 6.9
|
||||
+Description:
|
||||
+ Read/write binary blob representing the ASCII-to-7-segment
|
||||
+ display conversion table used by the linedisp driver, as defined
|
||||
+ by struct seg7_conversion_map in <linux/map_to_7segment.h>.
|
||||
+
|
||||
+ Only visible on displays with 7-segment capability.
|
||||
+
|
||||
+ This attribute is not human-readable. Writes must match the
|
||||
+ struct size exactly, else -EINVAL is returned; reads return the
|
||||
+ entire mapping as a binary blob.
|
||||
+
|
||||
+ This interface and its implementation match existing conventions
|
||||
+ used in segment-mapped display drivers since 2005.
|
||||
+
|
||||
+ ABI note: This style of binary sysfs attribute *is an exception*
|
||||
+ to current "one value per file, text only" sysfs rules, for
|
||||
+ historical compatibility and driver uniformity. New drivers are
|
||||
+ discouraged from introducing additional binary sysfs ABIs.
|
||||
+
|
||||
+ Reference interface guidance:
|
||||
+ - include/uapi/linux/map_to_7segment.h
|
||||
+
|
||||
+What: /sys/.../map_seg14
|
||||
+Date: January 2024
|
||||
+KernelVersion: 6.9
|
||||
+Description:
|
||||
+ Read/write binary blob representing the ASCII-to-14-segment
|
||||
+ display conversion table used by the linedisp driver, as defined
|
||||
+ by struct seg14_conversion_map in <linux/map_to_14segment.h>.
|
||||
+
|
||||
+ Only visible on displays with 14-segment capability.
|
||||
+
|
||||
+ This attribute is not human-readable. Writes must match the
|
||||
+ struct size exactly, else -EINVAL is returned; reads return the
|
||||
+ entire mapping as a binary blob.
|
||||
+
|
||||
+ This interface and its implementation match existing conventions
|
||||
+ used by segment-mapped display drivers since 2005.
|
||||
+
|
||||
+ ABI note: This style of binary sysfs attribute *is an exception*
|
||||
+ to current "one value per file, text only" sysfs rules, for
|
||||
+ historical compatibility and driver uniformity. New drivers are
|
||||
+ discouraged from introducing additional binary sysfs ABIs.
|
||||
+
|
||||
+ Reference interface guidance:
|
||||
+ - include/uapi/linux/map_to_14segment.h
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
From 0fadb57e2d1119fb45654fce943165d89961774c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Sat, 16 Aug 2025 16:17:06 -0400
|
||||
Subject: [PATCH 45/54] TEST: dt-bindings: vendor-prefixes: Add fdhisi,
|
||||
titanmec, princeton, winrise, wxicore
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add vendor prefixes of chip manufacturers supported by the TM16xx 7-segment
|
||||
LED matrix display controllers driver:
|
||||
- fdhisi: Fuzhou Fuda Hisi Microelectronics Co., Ltd.
|
||||
- titanmec: Shenzhen Titan Micro Electronics Co., Ltd.
|
||||
- princeton: Princeton Technology Corp.
|
||||
- winrise: Shenzhen Winrise Technology Co., Ltd.
|
||||
- wxicore: Wuxi i-Core Electronics Co., Ltd.
|
||||
|
||||
The titanmec prefix is based on the company's domain name titanmec.com.
|
||||
The remaining prefixes are based on company names, as these manufacturers
|
||||
either lack active .com domains or their .com domains are occupied by
|
||||
unrelated businesses.
|
||||
|
||||
The fdhisi and titanmec prefixes were originally identified by
|
||||
Andreas Färber.
|
||||
|
||||
CC: Andreas Färber <afaerber@suse.de>
|
||||
Acked-by: Conor Dooley <conor.dooley@microchip.com>
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/vendor-prefixes.yaml | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
index 5d2a7a8d3ac6..20b20ab8df47 100644
|
||||
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
|
||||
@@ -531,6 +531,8 @@ patternProperties:
|
||||
description: Fastrax Oy
|
||||
"^fcs,.*":
|
||||
description: Fairchild Semiconductor
|
||||
+ "^fdhisi,.*":
|
||||
+ description: Fuzhou Fuda Hisi Microelectronics Co., Ltd.
|
||||
"^feixin,.*":
|
||||
description: Shenzhen Feixin Photoelectic Co., Ltd
|
||||
"^feiyang,.*":
|
||||
@@ -1216,6 +1218,8 @@ patternProperties:
|
||||
description: Prime View International (PVI)
|
||||
"^primux,.*":
|
||||
description: Primux Trading, S.L.
|
||||
+ "^princeton,.*":
|
||||
+ description: Princeton Technology Corp.
|
||||
"^probox2,.*":
|
||||
description: PROBOX2 (by W2COMP Co., Ltd.)
|
||||
"^pri,.*":
|
||||
@@ -1548,6 +1552,8 @@ patternProperties:
|
||||
description: Texas Instruments
|
||||
"^tianma,.*":
|
||||
description: Tianma Micro-electronics Co., Ltd.
|
||||
+ "^titanmec,.*":
|
||||
+ description: Shenzhen Titan Micro Electronics Co., Ltd.
|
||||
"^tlm,.*":
|
||||
description: Trusted Logic Mobility
|
||||
"^tmt,.*":
|
||||
@@ -1705,6 +1711,8 @@ patternProperties:
|
||||
description: Wingtech Technology Co., Ltd.
|
||||
"^winlink,.*":
|
||||
description: WinLink Co., Ltd
|
||||
+ "^winrise,.*":
|
||||
+ description: Shenzhen Winrise Technology Co., Ltd.
|
||||
"^winsen,.*":
|
||||
description: Winsen Corp.
|
||||
"^winstar,.*":
|
||||
@@ -1721,6 +1729,8 @@ patternProperties:
|
||||
description: Wobo
|
||||
"^wolfvision,.*":
|
||||
description: WolfVision GmbH
|
||||
+ "^wxicore,.*":
|
||||
+ description: Wuxi i-Core Electronics Co., Ltd.
|
||||
"^x-powers,.*":
|
||||
description: X-Powers
|
||||
"^xen,.*":
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
From 7bf0f1ab8318fb1219f1140c53b01be6e7228533 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Mon, 1 Sep 2025 11:57:15 -0400
|
||||
Subject: [PATCH 46/54] TEST: dt-bindings: leds: add default-brightness
|
||||
property to common.yaml
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add default-brightness property to leds/common.yaml to establish a single
|
||||
canonical definition for LED brightness initialization.
|
||||
|
||||
The property is currently defined locally in leds/leds-pwm.yaml and is
|
||||
needed by auxdisplay/titanmec,tm16xx.yaml. Properties should be defined
|
||||
in only one location to avoid type inconsistencies across bindings.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/leds/common.yaml | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/leds/common.yaml b/Documentation/devicetree/bindings/leds/common.yaml
|
||||
index 3e8319e44339..96bd7fd0f053 100644
|
||||
--- a/Documentation/devicetree/bindings/leds/common.yaml
|
||||
+++ b/Documentation/devicetree/bindings/leds/common.yaml
|
||||
@@ -173,6 +173,12 @@ properties:
|
||||
led-max-microamp.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
+ default-brightness:
|
||||
+ description:
|
||||
+ Brightness to be set if LED's default state is on. Used only during
|
||||
+ initialization. If the option is not set then max brightness is used.
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint32
|
||||
+
|
||||
panic-indicator:
|
||||
description:
|
||||
This property specifies that the LED should be used, if at all possible,
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,529 @@
|
||||
From 78fa203f005c5d8f0947bc6c404720c61a1f8c0a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Mon, 1 Sep 2025 12:03:37 -0400
|
||||
Subject: [PATCH 47/54] TEST: dt-bindings: auxdisplay: add Titan Micro
|
||||
Electronics TM16xx
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add documentation for TM16xx-compatible 7-segment LED display controllers
|
||||
with keyscan.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
.../bindings/auxdisplay/titanmec,tm16xx.yaml | 485 ++++++++++++++++++
|
||||
MAINTAINERS | 5 +
|
||||
2 files changed, 490 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml b/Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml
|
||||
new file mode 100644
|
||||
index 000000000000..9b143baa8188
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml
|
||||
@@ -0,0 +1,485 @@
|
||||
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+%YAML 1.2
|
||||
+---
|
||||
+$id: http://devicetree.org/schemas/auxdisplay/titanmec,tm16xx.yaml#
|
||||
+$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
+
|
||||
+title: Auxiliary displays based on TM16xx and compatible LED controllers
|
||||
+
|
||||
+maintainers:
|
||||
+ - Jean-François Lessard <jefflessard3@gmail.com>
|
||||
+
|
||||
+description: |
|
||||
+ LED matrix controllers used in auxiliary display devices that drive individual
|
||||
+ LED icons and 7-segment digit groups through a grid/segment addressing scheme.
|
||||
+ Controllers manage a matrix of LEDs organized as grids (columns/banks in
|
||||
+ vendor datasheets) and segments (rows/bit positions in vendor datasheets).
|
||||
+ Maximum brightness and grid/segment indices are controller-specific.
|
||||
+ Controller-specific maximum are validated in the driver.
|
||||
+
|
||||
+ The controller is agnostic of the display layout. Board-specific LED wiring is
|
||||
+ described through child nodes that specify grid/segment coordinates for
|
||||
+ individual icons and segment mapping for 7-segment digits.
|
||||
+
|
||||
+ The bindings use separate 'leds' and 'digits' containers to accommodate
|
||||
+ different addressing schemes:
|
||||
+ - LEDs use 2-cell addressing (grid, segment) for matrix coordinates
|
||||
+ - Digits use 1-cell addressing with explicit segment mapping
|
||||
+
|
||||
+ The controller node exposes a logical LED-like control for the aggregate
|
||||
+ display brightness. Child nodes describe individual icons and 7-seg digits.
|
||||
+ The top-level control supports only label and brightness-related properties
|
||||
+ and does not support other common LED properties such as color or function.
|
||||
+ Child LED nodes use the standard LED binding.
|
||||
+
|
||||
+ Optional keypad scanning is supported when both 'linux,keymap' and
|
||||
+ 'poll-interval' properties are specified.
|
||||
+
|
||||
+properties:
|
||||
+ compatible:
|
||||
+ oneOf:
|
||||
+ - items:
|
||||
+ - enum:
|
||||
+ - fdhisi,fd628
|
||||
+ - princeton,pt6964
|
||||
+ - wxicore,aip1628
|
||||
+ - const: titanmec,tm1628
|
||||
+ - items:
|
||||
+ - enum:
|
||||
+ - wxicore,aip1618
|
||||
+ - const: titanmec,tm1618
|
||||
+ - items:
|
||||
+ - enum:
|
||||
+ - fdhisi,fd650
|
||||
+ - wxicore,aip650
|
||||
+ - const: titanmec,tm1650
|
||||
+ - enum:
|
||||
+ - fdhisi,fd620
|
||||
+ - fdhisi,fd655
|
||||
+ - fdhisi,fd6551
|
||||
+ - titanmec,tm1618
|
||||
+ - titanmec,tm1620
|
||||
+ - titanmec,tm1628
|
||||
+ - titanmec,tm1638
|
||||
+ - titanmec,tm1650
|
||||
+ - winrise,hbs658
|
||||
+
|
||||
+ reg:
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ label:
|
||||
+ description:
|
||||
+ The label for the top-level LED. If omitted, the label is taken from the
|
||||
+ node name (excluding the unit address). It has to uniquely identify a
|
||||
+ device, i.e. no other LED class device can be assigned the same label.
|
||||
+
|
||||
+ max-brightness:
|
||||
+ minimum: 0 # 0=off
|
||||
+ maximum: 8 # Maximum across all TM16xx controllers
|
||||
+ description:
|
||||
+ Normally the maximum brightness is determined by the hardware and this
|
||||
+ property is not required. This property is used to put a software limit
|
||||
+ on the brightness apart from what the driver says, as it could happen
|
||||
+ that a LED can be made so bright that it gets damaged or causes damage
|
||||
+ due to restrictions in a specific system, such as mounting conditions.
|
||||
+
|
||||
+ default-brightness:
|
||||
+ minimum: 0 # 0=off
|
||||
+ maximum: 8 # Maximum across all TM16xx controllers
|
||||
+ description:
|
||||
+ Brightness to be set if LED's default state is on. Used only during
|
||||
+ initialization. If the option is not set then max brightness is used.
|
||||
+
|
||||
+ digits:
|
||||
+ type: object
|
||||
+ description: Container for 7-segment digit group definitions
|
||||
+ additionalProperties: false
|
||||
+
|
||||
+ properties:
|
||||
+ "#address-cells":
|
||||
+ const: 1
|
||||
+ "#size-cells":
|
||||
+ const: 0
|
||||
+
|
||||
+ patternProperties:
|
||||
+ "^digit@[0-9]+$":
|
||||
+ type: object
|
||||
+ unevaluatedProperties: false
|
||||
+
|
||||
+ properties:
|
||||
+ reg:
|
||||
+ description:
|
||||
+ Digit position identifier numbered sequentially left-to-right,
|
||||
+ with reg=0 representing the leftmost digit position as displayed
|
||||
+ to the user.
|
||||
+ maxItems: 1
|
||||
+
|
||||
+ segments:
|
||||
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
|
||||
+ description: |
|
||||
+ Array of grid/segment coordinate pairs for each 7-segment position.
|
||||
+ Each entry is <grid segment> mapping to standard 7-segment positions
|
||||
+ in order: a, b, c, d, e, f, g
|
||||
+
|
||||
+ Standard 7-segment layout:
|
||||
+ aaa
|
||||
+ f b
|
||||
+ f b
|
||||
+ ggg
|
||||
+ e c
|
||||
+ e c
|
||||
+ ddd
|
||||
+ items:
|
||||
+ items:
|
||||
+ - description: Grid index
|
||||
+ - description: Segment index
|
||||
+ minItems: 7
|
||||
+ maxItems: 7
|
||||
+
|
||||
+ required:
|
||||
+ - reg
|
||||
+ - segments
|
||||
+
|
||||
+ leds:
|
||||
+ type: object
|
||||
+ description: Container for individual LED icon definitions
|
||||
+ additionalProperties: false
|
||||
+
|
||||
+ properties:
|
||||
+ "#address-cells":
|
||||
+ const: 2
|
||||
+ "#size-cells":
|
||||
+ const: 0
|
||||
+
|
||||
+ patternProperties:
|
||||
+ "^led@[0-9]+,[0-9]+$":
|
||||
+ type: object
|
||||
+ $ref: /schemas/leds/common.yaml#
|
||||
+ unevaluatedProperties: false
|
||||
+
|
||||
+ properties:
|
||||
+ reg:
|
||||
+ description:
|
||||
+ Grid and segment indices as <grid segment> of this individual LED icon
|
||||
+
|
||||
+ required:
|
||||
+ - reg
|
||||
+
|
||||
+dependencies:
|
||||
+ poll-interval:
|
||||
+ - linux,keymap
|
||||
+ linux,keymap:
|
||||
+ - poll-interval
|
||||
+ autorepeat:
|
||||
+ - linux,keymap
|
||||
+ - poll-interval
|
||||
+
|
||||
+required:
|
||||
+ - compatible
|
||||
+ - reg
|
||||
+
|
||||
+allOf:
|
||||
+ - $ref: /schemas/leds/common.yaml#
|
||||
+ properties:
|
||||
+ color: false
|
||||
+ function: false
|
||||
+ function-enumerator: false
|
||||
+ - $ref: /schemas/input/input.yaml#
|
||||
+ - $ref: /schemas/input/matrix-keymap.yaml#
|
||||
+ # SPI controllers require 3-wire (combined MISO/MOSI line)
|
||||
+ - if:
|
||||
+ properties:
|
||||
+ compatible:
|
||||
+ contains:
|
||||
+ enum:
|
||||
+ - fdhisi,fd620
|
||||
+ - fdhisi,fd628
|
||||
+ - princeton,pt6964
|
||||
+ - titanmec,tm1618
|
||||
+ - titanmec,tm1620
|
||||
+ - titanmec,tm1628
|
||||
+ - titanmec,tm1638
|
||||
+ - wxicore,aip1618
|
||||
+ - wxicore,aip1628
|
||||
+ then:
|
||||
+ $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
+ properties:
|
||||
+ spi-3wire: true
|
||||
+ required:
|
||||
+ - spi-3wire
|
||||
+
|
||||
+unevaluatedProperties: false
|
||||
+
|
||||
+examples:
|
||||
+ - |
|
||||
+ #include <dt-bindings/leds/common.h>
|
||||
+
|
||||
+ // I2C example: Magicsee N5 TV box with fd655 controller
|
||||
+ i2c {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ display@24 {
|
||||
+ reg = <0x24>;
|
||||
+ compatible = "fdhisi,fd655";
|
||||
+
|
||||
+ digits {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ digit@0 {
|
||||
+ reg = <0>;
|
||||
+ segments = <4 3>, <4 4>, <4 5>, <4 0>, <4 1>, <4 2>, <4 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@1 {
|
||||
+ reg = <1>;
|
||||
+ segments = <3 3>, <3 4>, <3 5>, <3 0>, <3 1>, <3 2>, <3 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@2 {
|
||||
+ reg = <2>;
|
||||
+ segments = <2 3>, <2 4>, <2 5>, <2 0>, <2 1>, <2 2>, <2 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@3 {
|
||||
+ reg = <3>;
|
||||
+ segments = <1 3>, <1 4>, <1 5>, <1 0>, <1 1>, <1 2>, <1 6>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ led@0,0 {
|
||||
+ reg = <0 0>;
|
||||
+ function = LED_FUNCTION_ALARM;
|
||||
+ };
|
||||
+
|
||||
+ led@0,1 {
|
||||
+ reg = <0 1>;
|
||||
+ function = LED_FUNCTION_USB;
|
||||
+ };
|
||||
+
|
||||
+ led@0,2 {
|
||||
+ reg = <0 2>;
|
||||
+ function = "play";
|
||||
+ };
|
||||
+
|
||||
+ led@0,3 {
|
||||
+ reg = <0 3>;
|
||||
+ function = "pause";
|
||||
+ };
|
||||
+
|
||||
+ led@0,4 {
|
||||
+ reg = <0 4>;
|
||||
+ function = "colon";
|
||||
+ };
|
||||
+
|
||||
+ led@0,5 {
|
||||
+ reg = <0 5>;
|
||||
+ function = LED_FUNCTION_LAN;
|
||||
+ };
|
||||
+
|
||||
+ led@0,6 {
|
||||
+ reg = <0 6>;
|
||||
+ function = LED_FUNCTION_WLAN;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ - |
|
||||
+ #include <dt-bindings/input/input.h>
|
||||
+
|
||||
+ // SPI example: TM1638 module with keypad support
|
||||
+ spi {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ display@0 {
|
||||
+ reg = <0>;
|
||||
+ compatible = "titanmec,tm1638";
|
||||
+ spi-3wire;
|
||||
+ spi-lsb-first;
|
||||
+ spi-max-frequency = <500000>;
|
||||
+
|
||||
+ label = "tm1638";
|
||||
+ default-brightness = <2>;
|
||||
+ max-brightness = <4>;
|
||||
+ poll-interval = <100>;
|
||||
+ linux,keymap = <MATRIX_KEY(2, 0, KEY_F1)
|
||||
+ MATRIX_KEY(2, 2, KEY_F2)
|
||||
+ MATRIX_KEY(2, 4, KEY_F3)
|
||||
+ MATRIX_KEY(2, 6, KEY_F4)
|
||||
+ MATRIX_KEY(2, 1, KEY_F5)
|
||||
+ MATRIX_KEY(2, 3, KEY_F6)
|
||||
+ MATRIX_KEY(2, 5, KEY_F7)
|
||||
+ MATRIX_KEY(2, 7, KEY_F8)>;
|
||||
+
|
||||
+ digits {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ digit@0 {
|
||||
+ reg = <0>;
|
||||
+ segments = <7 0>, <7 1>, <7 2>, <7 3>, <7 4>, <7 5>, <7 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@1 {
|
||||
+ reg = <1>;
|
||||
+ segments = <6 0>, <6 1>, <6 2>, <6 3>, <6 4>, <6 5>, <6 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@2 {
|
||||
+ reg = <2>;
|
||||
+ segments = <5 0>, <5 1>, <5 2>, <5 3>, <5 4>, <5 5>, <5 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@3 {
|
||||
+ reg = <3>;
|
||||
+ segments = <4 0>, <4 1>, <4 2>, <4 3>, <4 4>, <4 5>, <4 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@4 {
|
||||
+ reg = <4>;
|
||||
+ segments = <3 0>, <3 1>, <3 2>, <3 3>, <3 4>, <3 5>, <3 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@5 {
|
||||
+ reg = <5>;
|
||||
+ segments = <2 0>, <2 1>, <2 2>, <2 3>, <2 4>, <2 5>, <2 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@6 {
|
||||
+ reg = <6>;
|
||||
+ segments = <1 0>, <1 1>, <1 2>, <1 3>, <1 4>, <1 5>, <1 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@7 {
|
||||
+ reg = <7>;
|
||||
+ segments = <0 0>, <0 1>, <0 2>, <0 3>, <0 4>, <0 5>, <0 6>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ led@0,7 {
|
||||
+ reg = <0 7>;
|
||||
+ };
|
||||
+
|
||||
+ led@1,7 {
|
||||
+ reg = <1 7>;
|
||||
+ };
|
||||
+
|
||||
+ led@2,7 {
|
||||
+ reg = <2 7>;
|
||||
+ };
|
||||
+
|
||||
+ led@3,7 {
|
||||
+ reg = <3 7>;
|
||||
+ };
|
||||
+
|
||||
+ led@4,7 {
|
||||
+ reg = <4 7>;
|
||||
+ };
|
||||
+
|
||||
+ led@5,7 {
|
||||
+ reg = <5 7>;
|
||||
+ };
|
||||
+
|
||||
+ led@6,7 {
|
||||
+ reg = <6 7>;
|
||||
+ };
|
||||
+
|
||||
+ led@7,7 {
|
||||
+ reg = <7 7>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ - |
|
||||
+ #include <dt-bindings/leds/common.h>
|
||||
+
|
||||
+ // SPI example: X96 Max with transposed layout (fd628 with tm1628 fallback)
|
||||
+ spi {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ display@0 {
|
||||
+ reg = <0>;
|
||||
+ compatible = "fdhisi,fd628", "titanmec,tm1628";
|
||||
+ spi-3wire;
|
||||
+ spi-lsb-first;
|
||||
+ spi-max-frequency = <500000>;
|
||||
+
|
||||
+ digits {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ digit@0 {
|
||||
+ reg = <0>;
|
||||
+ segments = <0 3>, <1 3>, <2 3>, <3 3>, <4 3>, <5 3>, <6 3>;
|
||||
+ };
|
||||
+
|
||||
+ digit@1 {
|
||||
+ reg = <1>;
|
||||
+ segments = <0 2>, <1 2>, <2 2>, <3 2>, <4 2>, <5 2>, <6 2>;
|
||||
+ };
|
||||
+
|
||||
+ digit@2 {
|
||||
+ reg = <2>;
|
||||
+ segments = <0 1>, <1 1>, <2 1>, <3 1>, <4 1>, <5 1>, <6 1>;
|
||||
+ };
|
||||
+
|
||||
+ digit@3 {
|
||||
+ reg = <3>;
|
||||
+ segments = <0 0>, <1 0>, <2 0>, <3 0>, <4 0>, <5 0>, <6 0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ led@0,4 {
|
||||
+ reg = <0 4>;
|
||||
+ function = "apps";
|
||||
+ };
|
||||
+
|
||||
+ led@1,4 {
|
||||
+ reg = <1 4>;
|
||||
+ function = "setup";
|
||||
+ };
|
||||
+
|
||||
+ led@2,4 {
|
||||
+ reg = <2 4>;
|
||||
+ function = LED_FUNCTION_USB;
|
||||
+ };
|
||||
+
|
||||
+ led@3,4 {
|
||||
+ reg = <3 4>;
|
||||
+ function = LED_FUNCTION_SD;
|
||||
+ };
|
||||
+
|
||||
+ led@4,4 {
|
||||
+ reg = <4 4>;
|
||||
+ function = "colon";
|
||||
+ };
|
||||
+
|
||||
+ led@5,4 {
|
||||
+ reg = <5 4>;
|
||||
+ function = "hdmi";
|
||||
+ };
|
||||
+
|
||||
+ led@6,4 {
|
||||
+ reg = <6 4>;
|
||||
+ function = "video";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index c0b444e5fd5a..06b68aa9b6f8 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -25043,6 +25043,11 @@ W: http://sourceforge.net/projects/tlan/
|
||||
F: Documentation/networking/device_drivers/ethernet/ti/tlan.rst
|
||||
F: drivers/net/ethernet/ti/tlan.*
|
||||
|
||||
+TM16XX-COMPATIBLE LED CONTROLLERS DISPLAY DRIVER
|
||||
+M: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
+S: Maintained
|
||||
+F: Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml
|
||||
+
|
||||
TMIO/SDHI MMC DRIVER
|
||||
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
L: linux-mmc@vger.kernel.org
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,726 @@
|
||||
From b6c377ca8269ab4e4359700eb7a596acfdea9933 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Sat, 16 Aug 2025 20:52:21 -0400
|
||||
Subject: [PATCH 48/54] TEST: auxdisplay: Add TM16xx 7-segment LED matrix
|
||||
display controllers driver
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add driver for TM16xx family LED controllers and compatible chips from
|
||||
multiple vendors including Titan Micro, Fuda Hisi, i-Core, Princeton, and
|
||||
Winrise. These controllers drive 7-segment digits and individual LED icons
|
||||
through either I2C or SPI buses.
|
||||
|
||||
Successfully tested on various ARM TV boxes including H96 Max, Magicsee N5,
|
||||
Tanix TX3 Mini, Tanix TX6, X92, and X96 Max across different SoC platforms
|
||||
(Rockchip, Amlogic, Allwinner).
|
||||
|
||||
Acked-by: Paolo Sabatino <paolo.sabatino@gmail.com> # As primary user, integrated tm16xx into Armbian rockchip64
|
||||
Acked-by: Christian Hewitt <christianshewitt@gmail.com> # As primary user, integrated tm16xx into LibreElec
|
||||
Tested-by: Boris Gjenero <boris.gjenero@gmail.com> # Tested on X92
|
||||
Tested-by: Paolo Sabatino <paolo.sabatino@gmail.com> # Tested on H96 Max (XY_RK3328)
|
||||
Tested-by: Christian Hewitt <christianshewitt@gmail.com> # Tested on X96 Max, Tanix TX3 Mini
|
||||
Tested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> # Tested on Tanix TX3 Mini
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
MAINTAINERS | 3 +
|
||||
drivers/auxdisplay/Kconfig | 9 +
|
||||
drivers/auxdisplay/Makefile | 2 +
|
||||
drivers/auxdisplay/tm16xx.h | 172 ++++++++++++
|
||||
drivers/auxdisplay/tm16xx_core.c | 459 +++++++++++++++++++++++++++++++
|
||||
5 files changed, 645 insertions(+)
|
||||
create mode 100644 drivers/auxdisplay/tm16xx.h
|
||||
create mode 100644 drivers/auxdisplay/tm16xx_core.c
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 06b68aa9b6f8..e936dbe2ab0b 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -25046,7 +25046,10 @@ F: drivers/net/ethernet/ti/tlan.*
|
||||
TM16XX-COMPATIBLE LED CONTROLLERS DISPLAY DRIVER
|
||||
M: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
S: Maintained
|
||||
+F: Documentation/ABI/testing/sysfs-class-leds-tm16xx
|
||||
F: Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml
|
||||
+F: drivers/auxdisplay/tm16xx.h
|
||||
+F: drivers/auxdisplay/tm16xx_core.c
|
||||
|
||||
TMIO/SDHI MMC DRIVER
|
||||
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
|
||||
index bedc6133f970..7bacf11112b5 100644
|
||||
--- a/drivers/auxdisplay/Kconfig
|
||||
+++ b/drivers/auxdisplay/Kconfig
|
||||
@@ -526,6 +526,15 @@ config SEG_LED_GPIO
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called seg-led-gpio.
|
||||
|
||||
+config TM16XX
|
||||
+ tristate
|
||||
+ select LEDS_CLASS
|
||||
+ select LEDS_TRIGGERS
|
||||
+ select LINEDISP
|
||||
+ select NEW_LEDS
|
||||
+ help
|
||||
+ Core TM16XX-compatible 7-segment LED controllers module
|
||||
+
|
||||
#
|
||||
# Character LCD with non-conforming interface section
|
||||
#
|
||||
diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile
|
||||
index f5c13ed1cd4f..7ecf3cd4a0d3 100644
|
||||
--- a/drivers/auxdisplay/Makefile
|
||||
+++ b/drivers/auxdisplay/Makefile
|
||||
@@ -16,3 +16,5 @@ obj-$(CONFIG_LINEDISP) += line-display.o
|
||||
obj-$(CONFIG_MAX6959) += max6959.o
|
||||
obj-$(CONFIG_PARPORT_PANEL) += panel.o
|
||||
obj-$(CONFIG_SEG_LED_GPIO) += seg-led-gpio.o
|
||||
+obj-$(CONFIG_TM16XX) += tm16xx.o
|
||||
+tm16xx-y += tm16xx_core.o
|
||||
diff --git a/drivers/auxdisplay/tm16xx.h b/drivers/auxdisplay/tm16xx.h
|
||||
new file mode 100644
|
||||
index 000000000000..973b6ac19515
|
||||
--- /dev/null
|
||||
+++ b/drivers/auxdisplay/tm16xx.h
|
||||
@@ -0,0 +1,172 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+/*
|
||||
+ * TM16xx and compatible LED display/keypad controller driver
|
||||
+ * Supports TM16xx, FD6xx, PT6964, HBS658, AIP16xx and related chips.
|
||||
+ *
|
||||
+ * Copyright (C) 2025 Jean-François Lessard
|
||||
+ */
|
||||
+
|
||||
+#ifndef _TM16XX_H
|
||||
+#define _TM16XX_H
|
||||
+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/leds.h>
|
||||
+#include <linux/workqueue.h>
|
||||
+
|
||||
+#include "line-display.h"
|
||||
+
|
||||
+/* Common bit field definitions */
|
||||
+
|
||||
+/* Command type bits (bits 7-6) */
|
||||
+#define TM16XX_CMD_MASK GENMASK(7, 6)
|
||||
+#define TM16XX_CMD_MODE (0 << 6)
|
||||
+#define TM16XX_CMD_DATA (1 << 6)
|
||||
+#define TM16XX_CMD_CTRL (2 << 6)
|
||||
+#define TM16XX_CMD_ADDR (3 << 6)
|
||||
+#define TM16XX_CMD_WRITE (TM16XX_CMD_DATA | TM16XX_DATA_MODE_WRITE)
|
||||
+#define TM16XX_CMD_READ (TM16XX_CMD_DATA | TM16XX_DATA_MODE_READ)
|
||||
+
|
||||
+/* Mode command grid settings (bits 1-0) */
|
||||
+#define TM16XX_MODE_GRID_MASK GENMASK(1, 0)
|
||||
+#define TM16XX_MODE_4GRIDS (0 << 0)
|
||||
+#define TM16XX_MODE_5GRIDS (1 << 0)
|
||||
+#define TM16XX_MODE_6GRIDS (2 << 0)
|
||||
+#define TM16XX_MODE_7GRIDS (3 << 0)
|
||||
+
|
||||
+/* Data command settings */
|
||||
+#define TM16XX_DATA_ADDR_MASK BIT(2)
|
||||
+#define TM16XX_DATA_ADDR_AUTO (0 << 2)
|
||||
+#define TM16XX_DATA_ADDR_FIXED (1 << 2)
|
||||
+#define TM16XX_DATA_MODE_MASK GENMASK(1, 0)
|
||||
+#define TM16XX_DATA_MODE_WRITE (0 << 0)
|
||||
+#define TM16XX_DATA_MODE_READ (2 << 0)
|
||||
+
|
||||
+/* Control command settings */
|
||||
+#define TM16XX_CTRL_BR_MASK GENMASK(2, 0)
|
||||
+#define TM16XX_CTRL_ON (1 << 3)
|
||||
+
|
||||
+/* TM1618 specific constants */
|
||||
+#define TM1618_BYTE1_MASK GENMASK(4, 0)
|
||||
+#define TM1618_BYTE2_MASK GENMASK(7, 5)
|
||||
+#define TM1618_BYTE2_SHIFT 3
|
||||
+#define TM1618_KEY_READ_LEN 3
|
||||
+#define TM1618_KEY_MASK (BIT(4) | BIT(1))
|
||||
+
|
||||
+/* TM1628 specific constants */
|
||||
+#define TM1628_BYTE1_MASK GENMASK(7, 0)
|
||||
+#define TM1628_BYTE2_MASK GENMASK(13, 8)
|
||||
+#define TM1628_KEY_READ_LEN 5
|
||||
+#define TM1628_KEY_MASK (GENMASK(4, 3) | GENMASK(1, 0))
|
||||
+
|
||||
+/* TM1638 specific constants */
|
||||
+#define TM1638_KEY_READ_LEN 4
|
||||
+#define TM1638_KEY_MASK (GENMASK(6, 4) | GENMASK(2, 0))
|
||||
+
|
||||
+/* FD620 specific constants */
|
||||
+#define FD620_BYTE1_MASK GENMASK(6, 0)
|
||||
+
|
||||
+#define FD620_BYTE2_MASK BIT(7)
|
||||
+#define FD620_BYTE2_SHIFT 5
|
||||
+#define FD620_KEY_READ_LEN 4
|
||||
+#define FD620_KEY_MASK (BIT(3) | BIT(0))
|
||||
+
|
||||
+/* I2C controller addresses and control settings */
|
||||
+#define TM1650_CMD_CTRL 0x48
|
||||
+#define TM1650_CMD_READ 0x4F
|
||||
+#define TM1650_CMD_ADDR 0x68
|
||||
+#define TM1650_CTRL_BR_MASK GENMASK(6, 4)
|
||||
+#define TM1650_CTRL_ON (1 << 0)
|
||||
+#define TM1650_CTRL_SLEEP (1 << 2)
|
||||
+#define TM1650_CTRL_SEG_MASK BIT(3)
|
||||
+#define TM1650_CTRL_SEG8_MODE (0 << 3)
|
||||
+#define TM1650_CTRL_SEG7_MODE (1 << 3)
|
||||
+#define TM1650_KEY_ROW_MASK GENMASK(1, 0)
|
||||
+#define TM1650_KEY_COL_MASK GENMASK(5, 3)
|
||||
+#define TM1650_KEY_DOWN_MASK BIT(6)
|
||||
+#define TM1650_KEY_COMBINED GENMASK(5, 3)
|
||||
+
|
||||
+#define FD655_CMD_CTRL 0x48
|
||||
+#define FD655_CMD_ADDR 0x66
|
||||
+#define FD655_CTRL_BR_MASK GENMASK(6, 5)
|
||||
+#define FD655_CTRL_ON (1 << 0)
|
||||
+
|
||||
+#define FD6551_CMD_CTRL 0x48
|
||||
+#define FD6551_CTRL_BR_MASK GENMASK(3, 1)
|
||||
+#define FD6551_CTRL_ON (1 << 0)
|
||||
+
|
||||
+#define HBS658_KEY_COL_MASK GENMASK(7, 5)
|
||||
+
|
||||
+#define TM16XX_CTRL_BRIGHTNESS(on, val, prefix) \
|
||||
+ ((on) ? (FIELD_PREP(prefix##_CTRL_BR_MASK, (val)) | prefix##_CTRL_ON) : 0)
|
||||
+
|
||||
+/* Forward declarations */
|
||||
+struct tm16xx_display;
|
||||
+struct tm16xx_digit;
|
||||
+struct tm16xx_led;
|
||||
+
|
||||
+/**
|
||||
+ * DOC: struct tm16xx_controller - Controller-specific operations and limits
|
||||
+ * @max_grids: Maximum number of grids supported by the controller.
|
||||
+ * @max_segments: Maximum number of segments supported by the controller.
|
||||
+ * @max_brightness: Maximum brightness level supported by the controller.
|
||||
+ * @max_key_rows: Maximum number of key input rows supported by the controller.
|
||||
+ * @max_key_cols: Maximum number of key input columns supported by the controller.
|
||||
+ * @init: Pointer to controller mode/brightness configuration function.
|
||||
+ * @data: Pointer to function writing display data to the controller.
|
||||
+ * @keys: Pointer to function reading controller key state into bitmap.
|
||||
+ *
|
||||
+ * Holds function pointers and limits for controller-specific operations.
|
||||
+ */
|
||||
+struct tm16xx_controller {
|
||||
+ const u8 max_grids;
|
||||
+ const u8 max_segments;
|
||||
+ const u8 max_brightness;
|
||||
+ const u8 max_key_rows;
|
||||
+ const u8 max_key_cols;
|
||||
+ int (*const init)(struct tm16xx_display *display);
|
||||
+ int (*const data)(struct tm16xx_display *display, u8 index, unsigned int grid);
|
||||
+ int (*const keys)(struct tm16xx_display *display);
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct tm16xx_display - Main driver structure for the display
|
||||
+ * @dev: Pointer to device struct.
|
||||
+ * @controller: Controller-specific function table and limits.
|
||||
+ * @linedisp: character line display structure
|
||||
+ * @spi_buffer: DMA-safe buffer for SPI transactions, or NULL for I2C.
|
||||
+ * @num_hwgrid: Number of controller grids in use.
|
||||
+ * @num_hwseg: Number of controller segments in use.
|
||||
+ * @main_led: LED class device for the entire display.
|
||||
+ * @leds: Array of individual LED icon structures.
|
||||
+ * @num_leds: Number of individual LED icons.
|
||||
+ * @digits: Array of 7-segment digit structures.
|
||||
+ * @num_digits: Number of 7-segment digits.
|
||||
+ * @flush_init: Work struct for configuration update.
|
||||
+ * @flush_display: Work struct for display update.
|
||||
+ * @flush_status: Status/result of last flush work.
|
||||
+ * @lock: Mutex protecting concurrent access to work operations.
|
||||
+ * @state: Bitmap holding current raw display state.
|
||||
+ */
|
||||
+struct tm16xx_display {
|
||||
+ struct device *dev;
|
||||
+ const struct tm16xx_controller *controller;
|
||||
+ struct linedisp linedisp;
|
||||
+ u8 *spi_buffer;
|
||||
+ u8 num_hwgrid;
|
||||
+ u8 num_hwseg;
|
||||
+ struct led_classdev main_led;
|
||||
+ struct tm16xx_led *leds;
|
||||
+ u8 num_leds;
|
||||
+ struct tm16xx_digit *digits;
|
||||
+ u8 num_digits;
|
||||
+ struct work_struct flush_init;
|
||||
+ struct work_struct flush_display;
|
||||
+ int flush_status;
|
||||
+ struct mutex lock; /* prevents concurrent work operations */
|
||||
+ unsigned long *state;
|
||||
+};
|
||||
+
|
||||
+int tm16xx_probe(struct tm16xx_display *display);
|
||||
+void tm16xx_remove(struct tm16xx_display *display);
|
||||
+
|
||||
+#endif /* _TM16XX_H */
|
||||
diff --git a/drivers/auxdisplay/tm16xx_core.c b/drivers/auxdisplay/tm16xx_core.c
|
||||
new file mode 100644
|
||||
index 000000000000..e090c578f8a0
|
||||
--- /dev/null
|
||||
+++ b/drivers/auxdisplay/tm16xx_core.c
|
||||
@@ -0,0 +1,459 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * TM16xx and compatible LED display/keypad controller driver
|
||||
+ * Supports TM16xx, FD6xx, PT6964, HBS658, AIP16xx and related chips.
|
||||
+ *
|
||||
+ * Copyright (C) 2025 Jean-François Lessard
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/bitmap.h>
|
||||
+#include <linux/cleanup.h>
|
||||
+#include <linux/container_of.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/leds.h>
|
||||
+#include <linux/map_to_7segment.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/property.h>
|
||||
+#include <linux/sysfs.h>
|
||||
+#include <linux/workqueue.h>
|
||||
+
|
||||
+#include "line-display.h"
|
||||
+#include "tm16xx.h"
|
||||
+
|
||||
+#define TM16XX_DIGIT_SEGMENTS 7
|
||||
+
|
||||
+#define linedisp_to_tm16xx(display) \
|
||||
+ container_of(display, struct tm16xx_display, linedisp)
|
||||
+
|
||||
+/**
|
||||
+ * struct tm16xx_led - Individual LED icon mapping
|
||||
+ * @cdev: LED class device for sysfs interface.
|
||||
+ * @hwgrid: Controller grid index of the LED.
|
||||
+ * @hwseg: Controller segment index of the LED.
|
||||
+ */
|
||||
+struct tm16xx_led {
|
||||
+ struct led_classdev cdev;
|
||||
+ u8 hwgrid;
|
||||
+ u8 hwseg;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct tm16xx_digit - 7-segment digit mapping and value
|
||||
+ * @hwgrids: Array mapping each 7-segment position to a grid on the controller.
|
||||
+ * @hwsegs: Array mapping each 7-segment position to a segment on the controller.
|
||||
+ * @value: Current character value displayed on this digit.
|
||||
+ */
|
||||
+struct tm16xx_digit {
|
||||
+ u8 hwgrids[TM16XX_DIGIT_SEGMENTS];
|
||||
+ u8 hwsegs[TM16XX_DIGIT_SEGMENTS];
|
||||
+};
|
||||
+
|
||||
+/* state bitmap helpers */
|
||||
+/**
|
||||
+ * tm16xx_led_nbits() - Number of bits used for the display state bitmap
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ *
|
||||
+ * Return: total bits in the display state bitmap (grids * segments)
|
||||
+ */
|
||||
+static inline unsigned int tm16xx_led_nbits(const struct tm16xx_display *display)
|
||||
+{
|
||||
+ return display->num_hwgrid * display->num_hwseg;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_set_seg() - Set the display state for a specific grid/segment
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ * @hwgrid: grid index
|
||||
+ * @hwseg: segment index
|
||||
+ * @on: true to turn on, false to turn off
|
||||
+ */
|
||||
+static inline void tm16xx_set_seg(const struct tm16xx_display *display,
|
||||
+ const u8 hwgrid, const u8 hwseg, const bool on)
|
||||
+{
|
||||
+ assign_bit(hwgrid * display->num_hwseg + hwseg, display->state, on);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_get_grid() - Get the current segment pattern for a grid
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ * @index: grid index
|
||||
+ *
|
||||
+ * Return: bit pattern of all segments for the given grid
|
||||
+ */
|
||||
+static inline unsigned int tm16xx_get_grid(const struct tm16xx_display *display,
|
||||
+ const unsigned int index)
|
||||
+{
|
||||
+ return bitmap_read(display->state, index * display->num_hwseg,
|
||||
+ display->num_hwseg);
|
||||
+}
|
||||
+
|
||||
+/* main display */
|
||||
+/**
|
||||
+ * tm16xx_display_flush_init() - Workqueue to configure controller and set brightness
|
||||
+ * @work: pointer to work_struct
|
||||
+ */
|
||||
+static void tm16xx_display_flush_init(struct work_struct *work)
|
||||
+{
|
||||
+ struct tm16xx_display *display = container_of(work,
|
||||
+ struct tm16xx_display,
|
||||
+ flush_init);
|
||||
+ int ret;
|
||||
+
|
||||
+ if (display->controller->init) {
|
||||
+ scoped_guard(mutex, &display->lock) {
|
||||
+ ret = display->controller->init(display);
|
||||
+ display->flush_status = ret;
|
||||
+ }
|
||||
+ if (ret)
|
||||
+ dev_err(display->dev,
|
||||
+ "Failed to configure controller: %d\n", ret);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_display_flush_data() - Workqueue to update display data to controller
|
||||
+ * @work: pointer to work_struct
|
||||
+ */
|
||||
+static void tm16xx_display_flush_data(struct work_struct *work)
|
||||
+{
|
||||
+ struct tm16xx_display *display = container_of(work,
|
||||
+ struct tm16xx_display,
|
||||
+ flush_display);
|
||||
+ unsigned int grid, i;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ scoped_guard(mutex, &display->lock) {
|
||||
+ if (display->controller->data) {
|
||||
+ for (i = 0; i < display->num_hwgrid; i++) {
|
||||
+ grid = tm16xx_get_grid(display, i);
|
||||
+ ret = display->controller->data(display, i, grid);
|
||||
+ if (ret) {
|
||||
+ dev_err(display->dev,
|
||||
+ "Failed to write display data: %d\n",
|
||||
+ ret);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ display->flush_status = ret;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_brightness_set() - Set display main LED brightness
|
||||
+ * @led_cdev: pointer to led_classdev
|
||||
+ * @brightness: new brightness value
|
||||
+ */
|
||||
+static void tm16xx_brightness_set(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness brightness)
|
||||
+{
|
||||
+ struct tm16xx_display *display = dev_get_drvdata(led_cdev->dev->parent);
|
||||
+
|
||||
+ led_cdev->brightness = brightness;
|
||||
+ schedule_work(&display->flush_init);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_led_set() - Set state of an individual LED icon
|
||||
+ * @led_cdev: pointer to led_classdev
|
||||
+ * @value: new brightness (0/1)
|
||||
+ */
|
||||
+static void tm16xx_led_set(struct led_classdev *led_cdev,
|
||||
+ enum led_brightness value)
|
||||
+{
|
||||
+ struct tm16xx_led *led = container_of(led_cdev, struct tm16xx_led, cdev);
|
||||
+ struct tm16xx_display *display = dev_get_drvdata(led_cdev->dev->parent);
|
||||
+
|
||||
+ tm16xx_set_seg(display, led->hwgrid, led->hwseg, value);
|
||||
+ schedule_work(&display->flush_display);
|
||||
+}
|
||||
+
|
||||
+static int tm16xx_display_value(struct tm16xx_display *display, const char *buf, size_t count)
|
||||
+{
|
||||
+ struct linedisp *linedisp = &display->linedisp;
|
||||
+ struct linedisp_map *map = linedisp->map;
|
||||
+ struct tm16xx_digit *digit;
|
||||
+ unsigned int i, j;
|
||||
+ int seg_pattern;
|
||||
+ bool val;
|
||||
+
|
||||
+ for (i = 0; i < display->num_digits && i < count; i++) {
|
||||
+ digit = &display->digits[i];
|
||||
+ seg_pattern = map_to_seg7(&map->map.seg7, buf[i]);
|
||||
+
|
||||
+ for (j = 0; j < TM16XX_DIGIT_SEGMENTS; j++) {
|
||||
+ val = seg_pattern & BIT(j);
|
||||
+ tm16xx_set_seg(display, digit->hwgrids[j], digit->hwsegs[j], val);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (; i < display->num_digits; i++) {
|
||||
+ digit = &display->digits[i];
|
||||
+ for (j = 0; j < TM16XX_DIGIT_SEGMENTS; j++)
|
||||
+ tm16xx_set_seg(display, digit->hwgrids[j], digit->hwsegs[j], 0);
|
||||
+ }
|
||||
+
|
||||
+ schedule_work(&display->flush_display);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tm16xx_linedisp_get_map_type(struct linedisp *linedisp)
|
||||
+{
|
||||
+ return LINEDISP_MAP_SEG7;
|
||||
+}
|
||||
+
|
||||
+static void tm16xx_linedisp_update(struct linedisp *linedisp)
|
||||
+{
|
||||
+ struct tm16xx_display *display = linedisp_to_tm16xx(linedisp);
|
||||
+
|
||||
+ tm16xx_display_value(display, linedisp->buf, linedisp->num_chars);
|
||||
+}
|
||||
+
|
||||
+static const struct linedisp_ops tm16xx_linedisp_ops = {
|
||||
+ .get_map_type = tm16xx_linedisp_get_map_type,
|
||||
+ .update = tm16xx_linedisp_update,
|
||||
+};
|
||||
+
|
||||
+static int tm16xx_display_init(struct tm16xx_display *display)
|
||||
+{
|
||||
+ schedule_work(&display->flush_init);
|
||||
+ flush_work(&display->flush_init);
|
||||
+ if (display->flush_status)
|
||||
+ return display->flush_status;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tm16xx_parse_fwnode(struct device *dev, struct tm16xx_display *display)
|
||||
+{
|
||||
+ struct tm16xx_led *led;
|
||||
+ struct tm16xx_digit *digit;
|
||||
+ unsigned int max_hwgrid = 0, max_hwseg = 0;
|
||||
+ unsigned int i, j;
|
||||
+ int ret;
|
||||
+ u32 segments[TM16XX_DIGIT_SEGMENTS * 2];
|
||||
+ u32 reg[2];
|
||||
+
|
||||
+ struct fwnode_handle *digits_node __free(fwnode_handle) =
|
||||
+ device_get_named_child_node(dev, "digits");
|
||||
+ struct fwnode_handle *leds_node __free(fwnode_handle) =
|
||||
+ device_get_named_child_node(dev, "leds");
|
||||
+
|
||||
+ /* parse digits */
|
||||
+ if (digits_node) {
|
||||
+ display->num_digits = fwnode_get_child_node_count(digits_node);
|
||||
+
|
||||
+ if (display->num_digits) {
|
||||
+ display->digits = devm_kcalloc(dev, display->num_digits,
|
||||
+ sizeof(*display->digits),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!display->digits)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ i = 0;
|
||||
+ fwnode_for_each_available_child_node_scoped(digits_node, child) {
|
||||
+ digit = &display->digits[i];
|
||||
+
|
||||
+ ret = fwnode_property_read_u32(child, "reg", reg);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = fwnode_property_read_u32_array(child,
|
||||
+ "segments", segments,
|
||||
+ TM16XX_DIGIT_SEGMENTS * 2);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ for (j = 0; j < TM16XX_DIGIT_SEGMENTS; ++j) {
|
||||
+ digit->hwgrids[j] = segments[2 * j];
|
||||
+ digit->hwsegs[j] = segments[2 * j + 1];
|
||||
+ max_hwgrid = umax(max_hwgrid, digit->hwgrids[j]);
|
||||
+ max_hwseg = umax(max_hwseg, digit->hwsegs[j]);
|
||||
+ }
|
||||
+ i++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* parse leds */
|
||||
+ if (leds_node) {
|
||||
+ display->num_leds = fwnode_get_child_node_count(leds_node);
|
||||
+
|
||||
+ if (display->num_leds) {
|
||||
+ display->leds = devm_kcalloc(dev, display->num_leds,
|
||||
+ sizeof(*display->leds),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!display->leds)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ i = 0;
|
||||
+ fwnode_for_each_available_child_node_scoped(leds_node, child) {
|
||||
+ led = &display->leds[i];
|
||||
+ ret = fwnode_property_read_u32_array(child, "reg", reg, 2);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ led->hwgrid = reg[0];
|
||||
+ led->hwseg = reg[1];
|
||||
+ max_hwgrid = umax(max_hwgrid, led->hwgrid);
|
||||
+ max_hwseg = umax(max_hwseg, led->hwseg);
|
||||
+ i++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (max_hwgrid >= display->controller->max_grids) {
|
||||
+ dev_err(dev, "grid %u exceeds controller max_grids %u\n",
|
||||
+ max_hwgrid, display->controller->max_grids);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (max_hwseg >= display->controller->max_segments) {
|
||||
+ dev_err(dev, "segment %u exceeds controller max_segments %u\n",
|
||||
+ max_hwseg, display->controller->max_segments);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ display->num_hwgrid = max_hwgrid + 1;
|
||||
+ display->num_hwseg = max_hwseg + 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_probe() - Probe and initialize display device, register LEDs
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure
|
||||
+ */
|
||||
+int tm16xx_probe(struct tm16xx_display *display)
|
||||
+{
|
||||
+ struct device *dev = display->dev;
|
||||
+ struct led_classdev *main = &display->main_led;
|
||||
+ struct led_init_data led_init = {0};
|
||||
+ struct fwnode_handle *leds_node;
|
||||
+ struct tm16xx_led *led;
|
||||
+ unsigned int nbits, i;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = tm16xx_parse_fwnode(dev, display);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "Failed to parse device tree\n");
|
||||
+
|
||||
+ nbits = tm16xx_led_nbits(display);
|
||||
+ display->state = devm_bitmap_zalloc(dev, nbits, GFP_KERNEL);
|
||||
+ if (!display->state)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = devm_mutex_init(display->dev, &display->lock);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "Failed to initialize mutex\n");
|
||||
+
|
||||
+ INIT_WORK(&display->flush_init, tm16xx_display_flush_init);
|
||||
+ INIT_WORK(&display->flush_display, tm16xx_display_flush_data);
|
||||
+
|
||||
+ /* Initialize main LED properties */
|
||||
+ led_init.fwnode = dev_fwnode(dev); /* apply label property */
|
||||
+ main->max_brightness = display->controller->max_brightness;
|
||||
+ device_property_read_u32(dev, "max-brightness", &main->max_brightness);
|
||||
+ main->max_brightness = umin(main->max_brightness,
|
||||
+ display->controller->max_brightness);
|
||||
+
|
||||
+ main->brightness = main->max_brightness;
|
||||
+ device_property_read_u32(dev, "default-brightness", &main->brightness);
|
||||
+ main->brightness = umin(main->brightness, main->max_brightness);
|
||||
+
|
||||
+ main->brightness_set = tm16xx_brightness_set;
|
||||
+ main->flags = LED_RETAIN_AT_SHUTDOWN | LED_CORE_SUSPENDRESUME;
|
||||
+
|
||||
+ /* Register individual LEDs from device tree */
|
||||
+ ret = led_classdev_register_ext(dev, main, &led_init);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "Failed to register main LED\n");
|
||||
+
|
||||
+ i = 0;
|
||||
+ led_init.devicename = dev_name(main->dev);
|
||||
+ led_init.devname_mandatory = true;
|
||||
+ led_init.default_label = "led";
|
||||
+ leds_node = device_get_named_child_node(dev, "leds");
|
||||
+ fwnode_for_each_available_child_node_scoped(leds_node, child) {
|
||||
+ led_init.fwnode = child;
|
||||
+ led = &display->leds[i];
|
||||
+ led->cdev.max_brightness = 1;
|
||||
+ led->cdev.brightness_set = tm16xx_led_set;
|
||||
+ led->cdev.flags = LED_RETAIN_AT_SHUTDOWN | LED_CORE_SUSPENDRESUME;
|
||||
+
|
||||
+ ret = led_classdev_register_ext(dev, &led->cdev, &led_init);
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(dev, ret, "Failed to register LED %s\n",
|
||||
+ led->cdev.name);
|
||||
+ goto unregister_leds;
|
||||
+ }
|
||||
+
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ ret = tm16xx_display_init(display);
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(dev, ret, "Failed to initialize display\n");
|
||||
+ goto unregister_leds;
|
||||
+ }
|
||||
+
|
||||
+ ret = linedisp_attach(&display->linedisp, display->main_led.dev,
|
||||
+ display->num_digits, &tm16xx_linedisp_ops);
|
||||
+ if (ret) {
|
||||
+ dev_err_probe(dev, ret, "Failed to initialize line-display\n");
|
||||
+ goto unregister_leds;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+unregister_leds:
|
||||
+ while (i--)
|
||||
+ led_classdev_unregister(&display->leds[i].cdev);
|
||||
+
|
||||
+ led_classdev_unregister(main);
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS(tm16xx_probe, "TM16XX");
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_remove() - Remove display, unregister LEDs, blank output
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ */
|
||||
+void tm16xx_remove(struct tm16xx_display *display)
|
||||
+{
|
||||
+ unsigned int nbits = tm16xx_led_nbits(display);
|
||||
+ struct tm16xx_led *led;
|
||||
+
|
||||
+ linedisp_detach(display->main_led.dev);
|
||||
+
|
||||
+ /*
|
||||
+ * Unregister LEDs first to immediately stop trigger activity.
|
||||
+ * This prevents LED triggers from attempting to access hardware
|
||||
+ * after it's been disconnected or driver unloaded.
|
||||
+ */
|
||||
+ for (int i = 0; i < display->num_leds; i++) {
|
||||
+ led = &display->leds[i];
|
||||
+ led_classdev_unregister(&led->cdev);
|
||||
+ }
|
||||
+ led_classdev_unregister(&display->main_led);
|
||||
+
|
||||
+ /* Clear display state */
|
||||
+ bitmap_zero(display->state, nbits);
|
||||
+ schedule_work(&display->flush_display);
|
||||
+ flush_work(&display->flush_display);
|
||||
+
|
||||
+ /* Turn off display */
|
||||
+ display->main_led.brightness = LED_OFF;
|
||||
+ schedule_work(&display->flush_init);
|
||||
+ flush_work(&display->flush_init);
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS(tm16xx_remove, "TM16XX");
|
||||
+
|
||||
+MODULE_AUTHOR("Jean-François Lessard");
|
||||
+MODULE_DESCRIPTION("TM16xx LED Display Controllers");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_IMPORT_NS("LINEDISP");
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,357 @@
|
||||
From d485af66b4fb4e583aaaaf35a69cdead16ee090c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Fri, 29 Aug 2025 22:28:35 -0400
|
||||
Subject: [PATCH 49/54] TEST: auxdisplay: TM16xx: Add keypad support for
|
||||
scanning matrix keys
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add support for keypad scanning on TM16xx-compatible auxiliary display
|
||||
controllers. It handles keypad initialization, scanning, and input
|
||||
reporting for matrix keys managed by the TM16xx devices.
|
||||
|
||||
Key features include:
|
||||
- Input device registration configured by device properties
|
||||
(poll-interval, linux,keymap, autorepeat)
|
||||
- Key state tracking using managed bitmaps
|
||||
- Matrix scanning and event reporting integrated with Linux input
|
||||
subsystem
|
||||
|
||||
This code is separated from main core driver to improve maintainability
|
||||
and reviewability.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
drivers/auxdisplay/Kconfig | 9 ++
|
||||
drivers/auxdisplay/Makefile | 1 +
|
||||
drivers/auxdisplay/tm16xx.h | 25 ++++
|
||||
drivers/auxdisplay/tm16xx_core.c | 4 +
|
||||
drivers/auxdisplay/tm16xx_keypad.c | 196 +++++++++++++++++++++++++++++
|
||||
6 files changed, 236 insertions(+)
|
||||
create mode 100644 drivers/auxdisplay/tm16xx_keypad.c
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index e936dbe2ab0b..a5b66317a805 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -25050,6 +25050,7 @@ F: Documentation/ABI/testing/sysfs-class-leds-tm16xx
|
||||
F: Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml
|
||||
F: drivers/auxdisplay/tm16xx.h
|
||||
F: drivers/auxdisplay/tm16xx_core.c
|
||||
+F: drivers/auxdisplay/tm16xx_keypad.c
|
||||
|
||||
TMIO/SDHI MMC DRIVER
|
||||
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
|
||||
index 7bacf11112b5..f9a2c0641c3c 100644
|
||||
--- a/drivers/auxdisplay/Kconfig
|
||||
+++ b/drivers/auxdisplay/Kconfig
|
||||
@@ -528,13 +528,22 @@ config SEG_LED_GPIO
|
||||
|
||||
config TM16XX
|
||||
tristate
|
||||
+ depends on INPUT
|
||||
+ select INPUT_MATRIXKMAP
|
||||
select LEDS_CLASS
|
||||
select LEDS_TRIGGERS
|
||||
select LINEDISP
|
||||
select NEW_LEDS
|
||||
+ select TM16XX_KEYPAD if (INPUT)
|
||||
help
|
||||
Core TM16XX-compatible 7-segment LED controllers module
|
||||
|
||||
+config TM16XX_KEYPAD
|
||||
+ bool
|
||||
+ depends on TM16XX
|
||||
+ help
|
||||
+ Enable keyscan support for TM16XX driver.
|
||||
+
|
||||
#
|
||||
# Character LCD with non-conforming interface section
|
||||
#
|
||||
diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile
|
||||
index 7ecf3cd4a0d3..a9b9c8ff05e8 100644
|
||||
--- a/drivers/auxdisplay/Makefile
|
||||
+++ b/drivers/auxdisplay/Makefile
|
||||
@@ -18,3 +18,4 @@ obj-$(CONFIG_PARPORT_PANEL) += panel.o
|
||||
obj-$(CONFIG_SEG_LED_GPIO) += seg-led-gpio.o
|
||||
obj-$(CONFIG_TM16XX) += tm16xx.o
|
||||
tm16xx-y += tm16xx_core.o
|
||||
+tm16xx-$(CONFIG_TM16XX_KEYPAD) += tm16xx_keypad.o
|
||||
diff --git a/drivers/auxdisplay/tm16xx.h b/drivers/auxdisplay/tm16xx.h
|
||||
index 973b6ac19515..c503c6136807 100644
|
||||
--- a/drivers/auxdisplay/tm16xx.h
|
||||
+++ b/drivers/auxdisplay/tm16xx.h
|
||||
@@ -103,6 +103,7 @@
|
||||
struct tm16xx_display;
|
||||
struct tm16xx_digit;
|
||||
struct tm16xx_led;
|
||||
+struct tm16xx_keypad;
|
||||
|
||||
/**
|
||||
* DOC: struct tm16xx_controller - Controller-specific operations and limits
|
||||
@@ -133,6 +134,7 @@ struct tm16xx_controller {
|
||||
* @dev: Pointer to device struct.
|
||||
* @controller: Controller-specific function table and limits.
|
||||
* @linedisp: character line display structure
|
||||
+ * @keypad: Opaque pointer to tm16xx_keypad struct.
|
||||
* @spi_buffer: DMA-safe buffer for SPI transactions, or NULL for I2C.
|
||||
* @num_hwgrid: Number of controller grids in use.
|
||||
* @num_hwseg: Number of controller segments in use.
|
||||
@@ -150,6 +152,7 @@ struct tm16xx_controller {
|
||||
struct tm16xx_display {
|
||||
struct device *dev;
|
||||
const struct tm16xx_controller *controller;
|
||||
+ struct tm16xx_keypad *keypad;
|
||||
struct linedisp linedisp;
|
||||
u8 *spi_buffer;
|
||||
u8 num_hwgrid;
|
||||
@@ -169,4 +172,26 @@ struct tm16xx_display {
|
||||
int tm16xx_probe(struct tm16xx_display *display);
|
||||
void tm16xx_remove(struct tm16xx_display *display);
|
||||
|
||||
+/* keypad support */
|
||||
+#if IS_ENABLED(CONFIG_TM16XX_KEYPAD)
|
||||
+int tm16xx_keypad_probe(struct tm16xx_display *display);
|
||||
+void tm16xx_set_key(const struct tm16xx_display *display, const int row,
|
||||
+ const int col, const bool pressed);
|
||||
+#else
|
||||
+static inline int tm16xx_keypad_probe(struct tm16xx_display *display)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void tm16xx_set_key(const struct tm16xx_display *display,
|
||||
+ const int row, const int col,
|
||||
+ const bool pressed)
|
||||
+{
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#define tm16xx_for_each_key(display, _r, _c) \
|
||||
+ for (int _r = 0; _r < (display)->controller->max_key_rows; _r++) \
|
||||
+ for (int _c = 0; _c < (display)->controller->max_key_cols; _c++)
|
||||
+
|
||||
#endif /* _TM16XX_H */
|
||||
diff --git a/drivers/auxdisplay/tm16xx_core.c b/drivers/auxdisplay/tm16xx_core.c
|
||||
index e090c578f8a0..1d474d980254 100644
|
||||
--- a/drivers/auxdisplay/tm16xx_core.c
|
||||
+++ b/drivers/auxdisplay/tm16xx_core.c
|
||||
@@ -408,6 +408,10 @@ int tm16xx_probe(struct tm16xx_display *display)
|
||||
goto unregister_leds;
|
||||
}
|
||||
|
||||
+ ret = tm16xx_keypad_probe(display);
|
||||
+ if (ret)
|
||||
+ dev_warn(dev, "Failed to initialize keypad: %d\n", ret);
|
||||
+
|
||||
return 0;
|
||||
|
||||
unregister_leds:
|
||||
diff --git a/drivers/auxdisplay/tm16xx_keypad.c b/drivers/auxdisplay/tm16xx_keypad.c
|
||||
new file mode 100644
|
||||
index 000000000000..daa6afaf749a
|
||||
--- /dev/null
|
||||
+++ b/drivers/auxdisplay/tm16xx_keypad.c
|
||||
@@ -0,0 +1,196 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * TM16xx and compatible LED display/keypad controller driver
|
||||
+ * Supports TM16xx, FD6xx, PT6964, HBS658, AIP16xx and related chips.
|
||||
+ *
|
||||
+ * Copyright (C) 2025 Jean-François Lessard
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitmap.h>
|
||||
+#include <linux/cleanup.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/input.h>
|
||||
+#include <linux/input/matrix_keypad.h>
|
||||
+#include <linux/property.h>
|
||||
+
|
||||
+#include "tm16xx.h"
|
||||
+
|
||||
+/**
|
||||
+ * struct tm16xx_keypad - Keypad matrix state and input device
|
||||
+ * @input: Input device for reporting key events.
|
||||
+ * @state: Current bitmap of key states.
|
||||
+ * @last_state: Previous bitmap of key states for change detection.
|
||||
+ * @changes: Bitmap of key state changes since last poll.
|
||||
+ * @row_shift: Row shift for keymap encoding.
|
||||
+ */
|
||||
+struct tm16xx_keypad {
|
||||
+ struct input_dev *input;
|
||||
+ unsigned long *state;
|
||||
+ unsigned long *last_state;
|
||||
+ unsigned long *changes;
|
||||
+ int row_shift;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_key_nbits() - Number of bits for the keypad state bitmap
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ *
|
||||
+ * Return: total bits in keypad state bitmap (max_key_rows * max_key_cols)
|
||||
+ */
|
||||
+static inline unsigned int tm16xx_key_nbits(const struct tm16xx_display *display)
|
||||
+{
|
||||
+ return display->controller->max_key_rows *
|
||||
+ display->controller->max_key_cols;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_get_key_row() - Get row index from keypad bit index
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ * @bit: bit index in state bitmap
|
||||
+ *
|
||||
+ * Return: row index
|
||||
+ */
|
||||
+static inline int tm16xx_get_key_row(const struct tm16xx_display *display,
|
||||
+ const unsigned int bit)
|
||||
+{
|
||||
+ return bit / display->controller->max_key_cols;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_get_key_col() - Get column index from keypad bit index
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ * @bit: bit index in state bitmap
|
||||
+ *
|
||||
+ * Return: column index
|
||||
+ */
|
||||
+static inline int tm16xx_get_key_col(const struct tm16xx_display *display,
|
||||
+ const unsigned int bit)
|
||||
+{
|
||||
+ return bit % display->controller->max_key_cols;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_set_key() - Set the keypad state for a key
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ * @row: row index
|
||||
+ * @col: column index
|
||||
+ * @pressed: true if pressed, false otherwise
|
||||
+ */
|
||||
+void tm16xx_set_key(const struct tm16xx_display *display, const int row,
|
||||
+ const int col, const bool pressed)
|
||||
+{
|
||||
+ __assign_bit(row * display->controller->max_key_cols + col,
|
||||
+ display->keypad->state, pressed);
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS(tm16xx_set_key, "TM16XX");
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_keypad_poll() - Polls the keypad, reports events
|
||||
+ * @input: pointer to input_dev
|
||||
+ *
|
||||
+ * Reads the matrix keypad state, compares with previous state, and
|
||||
+ * reports key events to the input subsystem.
|
||||
+ */
|
||||
+static void tm16xx_keypad_poll(struct input_dev *input)
|
||||
+{
|
||||
+ struct tm16xx_display *display = input_get_drvdata(input);
|
||||
+ struct tm16xx_keypad *keypad = display->keypad;
|
||||
+ const unsigned short *keycodes = keypad->input->keycode;
|
||||
+ unsigned int nbits = tm16xx_key_nbits(display);
|
||||
+ unsigned int bit;
|
||||
+ int row, col, scancode;
|
||||
+ bool pressed;
|
||||
+ int ret;
|
||||
+
|
||||
+ bitmap_zero(keypad->state, nbits);
|
||||
+ bitmap_zero(keypad->changes, nbits);
|
||||
+
|
||||
+ scoped_guard(mutex, &display->lock) {
|
||||
+ ret = display->controller->keys(display);
|
||||
+ }
|
||||
+
|
||||
+ if (ret) {
|
||||
+ dev_err(display->dev, "Reading failed: %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ bitmap_xor(keypad->changes, keypad->state, keypad->last_state, nbits);
|
||||
+
|
||||
+ for_each_set_bit(bit, keypad->changes, nbits) {
|
||||
+ row = tm16xx_get_key_row(display, bit);
|
||||
+ col = tm16xx_get_key_col(display, bit);
|
||||
+ pressed = _test_bit(bit, keypad->state);
|
||||
+ scancode = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
|
||||
+
|
||||
+ input_event(keypad->input, EV_MSC, MSC_SCAN, scancode);
|
||||
+ input_report_key(keypad->input, keycodes[scancode], pressed);
|
||||
+ }
|
||||
+ input_sync(keypad->input);
|
||||
+
|
||||
+ bitmap_copy(keypad->last_state, keypad->state, nbits);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_keypad_probe() - Initialize keypad/input device
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure
|
||||
+ */
|
||||
+int tm16xx_keypad_probe(struct tm16xx_display *display)
|
||||
+{
|
||||
+ const unsigned int rows = display->controller->max_key_rows;
|
||||
+ const unsigned int cols = display->controller->max_key_cols;
|
||||
+ struct tm16xx_keypad *keypad;
|
||||
+ struct input_dev *input;
|
||||
+ unsigned int poll_interval, nbits;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!display->controller->keys || !rows || !cols)
|
||||
+ return 0; /* keypad not supported */
|
||||
+
|
||||
+ if (!device_property_present(display->dev, "poll-interval") ||
|
||||
+ !device_property_present(display->dev, "linux,keymap"))
|
||||
+ return 0; /* keypad disabled */
|
||||
+
|
||||
+ ret = device_property_read_u32(display->dev, "poll-interval", &poll_interval);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(display->dev, ret,
|
||||
+ "Failed to read poll-interval\n");
|
||||
+
|
||||
+ keypad = devm_kzalloc(display->dev, sizeof(*keypad), GFP_KERNEL);
|
||||
+ if (!keypad)
|
||||
+ return -ENOMEM;
|
||||
+ display->keypad = keypad;
|
||||
+
|
||||
+ nbits = tm16xx_key_nbits(display);
|
||||
+ keypad->state = devm_bitmap_zalloc(display->dev, nbits, GFP_KERNEL);
|
||||
+ keypad->last_state = devm_bitmap_zalloc(display->dev, nbits, GFP_KERNEL);
|
||||
+ keypad->changes = devm_bitmap_zalloc(display->dev, nbits, GFP_KERNEL);
|
||||
+ if (!keypad->state || !keypad->last_state || !keypad->changes)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ input = devm_input_allocate_device(display->dev);
|
||||
+ if (!input)
|
||||
+ return -ENOMEM;
|
||||
+ input->name = "tm16xx-keypad";
|
||||
+ keypad->input = input;
|
||||
+ input_set_drvdata(input, display);
|
||||
+
|
||||
+ keypad->row_shift = get_count_order(cols); /* !cols already checked */
|
||||
+ ret = matrix_keypad_build_keymap(NULL, "linux,keymap", rows, cols, NULL, input);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(display->dev, ret,
|
||||
+ "Failed to build keymap\n");
|
||||
+
|
||||
+ if (device_property_read_bool(display->dev, "autorepeat"))
|
||||
+ __set_bit(EV_REP, input->evbit);
|
||||
+
|
||||
+ input_setup_polling(input, tm16xx_keypad_poll);
|
||||
+ input_set_poll_interval(input, poll_interval);
|
||||
+ ret = input_register_device(input);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(display->dev, ret,
|
||||
+ "Failed to register input device\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,419 @@
|
||||
From 1dbdfd4092b51f693c7055c8fea169369db96f8f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Sat, 23 Aug 2025 21:26:59 -0400
|
||||
Subject: [PATCH 50/54] TEST: auxdisplay: TM16xx: Add support for I2C-based
|
||||
controllers
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add support for TM16xx-compatible auxiliary display controllers connected
|
||||
via the I2C bus.
|
||||
|
||||
The implementation includes:
|
||||
- I2C driver registration and initialization
|
||||
- Probe/remove logic for I2C devices
|
||||
- Controller-specific handling and communication sequences
|
||||
- Integration with the TM16xx core driver for common functionality
|
||||
|
||||
This allows platforms using TM16xx or compatible controllers over I2C to be
|
||||
managed by the TM16xx driver infrastructure.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
drivers/auxdisplay/Kconfig | 16 ++
|
||||
drivers/auxdisplay/Makefile | 1 +
|
||||
drivers/auxdisplay/tm16xx_i2c.c | 332 ++++++++++++++++++++++++++++++++
|
||||
4 files changed, 350 insertions(+)
|
||||
create mode 100644 drivers/auxdisplay/tm16xx_i2c.c
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index a5b66317a805..f1354b5c9bd7 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -25050,6 +25050,7 @@ F: Documentation/ABI/testing/sysfs-class-leds-tm16xx
|
||||
F: Documentation/devicetree/bindings/auxdisplay/titanmec,tm16xx.yaml
|
||||
F: drivers/auxdisplay/tm16xx.h
|
||||
F: drivers/auxdisplay/tm16xx_core.c
|
||||
+F: drivers/auxdisplay/tm16xx_i2c.c
|
||||
F: drivers/auxdisplay/tm16xx_keypad.c
|
||||
|
||||
TMIO/SDHI MMC DRIVER
|
||||
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
|
||||
index f9a2c0641c3c..d48c2f18950e 100644
|
||||
--- a/drivers/auxdisplay/Kconfig
|
||||
+++ b/drivers/auxdisplay/Kconfig
|
||||
@@ -544,6 +544,22 @@ config TM16XX_KEYPAD
|
||||
help
|
||||
Enable keyscan support for TM16XX driver.
|
||||
|
||||
+config TM16XX_I2C
|
||||
+ tristate "TM16XX-compatible I2C 7-segment LED controllers with keyscan"
|
||||
+ depends on I2C
|
||||
+ select TM16XX
|
||||
+ help
|
||||
+ This driver supports the following TM16XX compatible
|
||||
+ I2C (2-wire) 7-segment led display chips:
|
||||
+ - Titanmec: TM1650
|
||||
+ - Fuda Hisi: FD650, FD655, FD6551
|
||||
+ - i-Core: AiP650
|
||||
+ - Winrise: HBS658
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called tm16xx_i2c and you will also get tm16xx for the
|
||||
+ core module.
|
||||
+
|
||||
#
|
||||
# Character LCD with non-conforming interface section
|
||||
#
|
||||
diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile
|
||||
index a9b9c8ff05e8..ba7b310f5667 100644
|
||||
--- a/drivers/auxdisplay/Makefile
|
||||
+++ b/drivers/auxdisplay/Makefile
|
||||
@@ -19,3 +19,4 @@ obj-$(CONFIG_SEG_LED_GPIO) += seg-led-gpio.o
|
||||
obj-$(CONFIG_TM16XX) += tm16xx.o
|
||||
tm16xx-y += tm16xx_core.o
|
||||
tm16xx-$(CONFIG_TM16XX_KEYPAD) += tm16xx_keypad.o
|
||||
+obj-$(CONFIG_TM16XX_I2C) += tm16xx_i2c.o
|
||||
diff --git a/drivers/auxdisplay/tm16xx_i2c.c b/drivers/auxdisplay/tm16xx_i2c.c
|
||||
new file mode 100644
|
||||
index 000000000000..013becedac11
|
||||
--- /dev/null
|
||||
+++ b/drivers/auxdisplay/tm16xx_i2c.c
|
||||
@@ -0,0 +1,332 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * TM16xx and compatible LED display/keypad controller driver
|
||||
+ * Supports TM16xx, FD6xx, PT6964, HBS658, AIP16xx and related chips.
|
||||
+ *
|
||||
+ * Copyright (C) 2025 Jean-François Lessard
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/mod_devicetable.h>
|
||||
+#include <linux/module.h>
|
||||
+
|
||||
+#include "tm16xx.h"
|
||||
+
|
||||
+static int tm16xx_i2c_probe(struct i2c_client *client)
|
||||
+{
|
||||
+ const struct tm16xx_controller *controller;
|
||||
+ struct tm16xx_display *display;
|
||||
+ int ret;
|
||||
+
|
||||
+ controller = i2c_get_match_data(client);
|
||||
+ if (!controller)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ display = devm_kzalloc(&client->dev, sizeof(*display), GFP_KERNEL);
|
||||
+ if (!display)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ display->dev = &client->dev;
|
||||
+ display->controller = controller;
|
||||
+
|
||||
+ i2c_set_clientdata(client, display);
|
||||
+
|
||||
+ ret = tm16xx_probe(display);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void tm16xx_i2c_remove(struct i2c_client *client)
|
||||
+{
|
||||
+ struct tm16xx_display *display = i2c_get_clientdata(client);
|
||||
+
|
||||
+ tm16xx_remove(display);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_i2c_write() - I2C write helper for controller
|
||||
+ * @display: pointer to tm16xx_display structure
|
||||
+ * @data: command and data bytes to send
|
||||
+ * @len: number of bytes in @data
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure
|
||||
+ */
|
||||
+static int tm16xx_i2c_write(struct tm16xx_display *display, u8 *data, size_t len)
|
||||
+{
|
||||
+ struct i2c_client *i2c = to_i2c_client(display->dev);
|
||||
+
|
||||
+ /* expected sequence: S Command [A] Data [A] P */
|
||||
+ struct i2c_msg msg = {
|
||||
+ .addr = data[0] >> 1,
|
||||
+ .flags = 0,
|
||||
+ .len = len - 1,
|
||||
+ .buf = &data[1],
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = i2c_transfer(i2c->adapter, &msg, 1);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return (ret == 1) ? 0 : -EIO;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_i2c_read() - I2C read helper for controller
|
||||
+ * @display: pointer to tm16xx_display structure
|
||||
+ * @cmd: command/address byte to send before reading
|
||||
+ * @data: buffer to receive data
|
||||
+ * @len: number of bytes to read into @data
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure
|
||||
+ */
|
||||
+static int tm16xx_i2c_read(struct tm16xx_display *display, u8 cmd, u8 *data, size_t len)
|
||||
+{
|
||||
+ struct i2c_client *i2c = to_i2c_client(display->dev);
|
||||
+
|
||||
+ /* expected sequence: S Command [A] [Data] [A] P */
|
||||
+ struct i2c_msg msgs[1] = {{
|
||||
+ .addr = cmd >> 1,
|
||||
+ .flags = I2C_M_RD | I2C_M_NO_RD_ACK,
|
||||
+ .len = len,
|
||||
+ .buf = data,
|
||||
+ }};
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = i2c_transfer(i2c->adapter, msgs, ARRAY_SIZE(msgs));
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return (ret == ARRAY_SIZE(msgs)) ? 0 : -EIO;
|
||||
+}
|
||||
+
|
||||
+/* I2C controller-specific functions */
|
||||
+static int tm1650_init(struct tm16xx_display *display)
|
||||
+{
|
||||
+ const enum led_brightness brightness = display->main_led.brightness;
|
||||
+ u8 cmds[2];
|
||||
+
|
||||
+ cmds[0] = TM1650_CMD_CTRL;
|
||||
+ cmds[1] = TM16XX_CTRL_BRIGHTNESS(brightness, brightness, TM1650) |
|
||||
+ TM1650_CTRL_SEG8_MODE;
|
||||
+
|
||||
+ return tm16xx_i2c_write(display, cmds, ARRAY_SIZE(cmds));
|
||||
+}
|
||||
+
|
||||
+static int tm1650_data(struct tm16xx_display *display, u8 index,
|
||||
+ unsigned int grid)
|
||||
+{
|
||||
+ u8 cmds[2];
|
||||
+
|
||||
+ cmds[0] = TM1650_CMD_ADDR + index * 2;
|
||||
+ cmds[1] = grid; /* SEG 1 to 8 */
|
||||
+
|
||||
+ return tm16xx_i2c_write(display, cmds, ARRAY_SIZE(cmds));
|
||||
+}
|
||||
+
|
||||
+static int tm1650_keys(struct tm16xx_display *display)
|
||||
+{
|
||||
+ int row, col;
|
||||
+ bool pressed;
|
||||
+ u8 keycode;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = tm16xx_i2c_read(display, TM1650_CMD_READ, &keycode, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (keycode == 0x00 || keycode == 0xFF)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ row = FIELD_GET(TM1650_KEY_ROW_MASK, keycode);
|
||||
+ pressed = FIELD_GET(TM1650_KEY_DOWN_MASK, keycode) != 0;
|
||||
+ if ((keycode & TM1650_KEY_COMBINED) == TM1650_KEY_COMBINED) {
|
||||
+ tm16xx_set_key(display, row, 0, pressed);
|
||||
+ tm16xx_set_key(display, row, 1, pressed);
|
||||
+ } else {
|
||||
+ col = FIELD_GET(TM1650_KEY_COL_MASK, keycode);
|
||||
+ tm16xx_set_key(display, row, col, pressed);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int fd655_init(struct tm16xx_display *display)
|
||||
+{
|
||||
+ const enum led_brightness brightness = display->main_led.brightness;
|
||||
+ u8 cmds[2];
|
||||
+
|
||||
+ cmds[0] = FD655_CMD_CTRL;
|
||||
+ cmds[1] = TM16XX_CTRL_BRIGHTNESS(brightness, brightness % 3, FD655);
|
||||
+
|
||||
+ return tm16xx_i2c_write(display, cmds, ARRAY_SIZE(cmds));
|
||||
+}
|
||||
+
|
||||
+static int fd655_data(struct tm16xx_display *display, u8 index,
|
||||
+ unsigned int grid)
|
||||
+{
|
||||
+ u8 cmds[2];
|
||||
+
|
||||
+ cmds[0] = FD655_CMD_ADDR + index * 2;
|
||||
+ cmds[1] = grid; /* SEG 1 to 8 */
|
||||
+
|
||||
+ return tm16xx_i2c_write(display, cmds, ARRAY_SIZE(cmds));
|
||||
+}
|
||||
+
|
||||
+static int fd6551_init(struct tm16xx_display *display)
|
||||
+{
|
||||
+ const enum led_brightness brightness = display->main_led.brightness;
|
||||
+ u8 cmds[2];
|
||||
+
|
||||
+ cmds[0] = FD6551_CMD_CTRL;
|
||||
+ cmds[1] = TM16XX_CTRL_BRIGHTNESS(brightness, ~(brightness - 1), FD6551);
|
||||
+
|
||||
+ return tm16xx_i2c_write(display, cmds, ARRAY_SIZE(cmds));
|
||||
+}
|
||||
+
|
||||
+static void hbs658_swap_nibbles(u8 *data, size_t len)
|
||||
+{
|
||||
+ for (size_t i = 0; i < len; i++)
|
||||
+ data[i] = (data[i] << 4) | (data[i] >> 4);
|
||||
+}
|
||||
+
|
||||
+static int hbs658_init(struct tm16xx_display *display)
|
||||
+{
|
||||
+ const enum led_brightness brightness = display->main_led.brightness;
|
||||
+ u8 cmd;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Set data command */
|
||||
+ cmd = TM16XX_CMD_WRITE | TM16XX_DATA_ADDR_AUTO;
|
||||
+ hbs658_swap_nibbles(&cmd, 1);
|
||||
+ ret = tm16xx_i2c_write(display, &cmd, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Set control command with brightness */
|
||||
+ cmd = TM16XX_CMD_CTRL |
|
||||
+ TM16XX_CTRL_BRIGHTNESS(brightness, brightness - 1, TM16XX);
|
||||
+ hbs658_swap_nibbles(&cmd, 1);
|
||||
+ ret = tm16xx_i2c_write(display, &cmd, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int hbs658_data(struct tm16xx_display *display, u8 index,
|
||||
+ unsigned int grid)
|
||||
+{
|
||||
+ u8 cmds[2];
|
||||
+
|
||||
+ cmds[0] = TM16XX_CMD_ADDR + index * 2;
|
||||
+ cmds[1] = grid;
|
||||
+
|
||||
+ hbs658_swap_nibbles(cmds, ARRAY_SIZE(cmds));
|
||||
+ return tm16xx_i2c_write(display, cmds, ARRAY_SIZE(cmds));
|
||||
+}
|
||||
+
|
||||
+static int hbs658_keys(struct tm16xx_display *display)
|
||||
+{
|
||||
+ u8 cmd, keycode;
|
||||
+ int col;
|
||||
+ int ret;
|
||||
+
|
||||
+ cmd = TM16XX_CMD_READ;
|
||||
+ hbs658_swap_nibbles(&cmd, 1);
|
||||
+ ret = tm16xx_i2c_read(display, cmd, &keycode, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ hbs658_swap_nibbles(&keycode, 1);
|
||||
+
|
||||
+ if (keycode != 0xFF) {
|
||||
+ col = FIELD_GET(HBS658_KEY_COL_MASK, keycode);
|
||||
+ tm16xx_set_key(display, 0, col, true);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* I2C controller definitions */
|
||||
+static const struct tm16xx_controller tm1650_controller = {
|
||||
+ .max_grids = 4,
|
||||
+ .max_segments = 8,
|
||||
+ .max_brightness = 8,
|
||||
+ .max_key_rows = 4,
|
||||
+ .max_key_cols = 7,
|
||||
+ .init = tm1650_init,
|
||||
+ .data = tm1650_data,
|
||||
+ .keys = tm1650_keys,
|
||||
+};
|
||||
+
|
||||
+static const struct tm16xx_controller fd655_controller = {
|
||||
+ .max_grids = 5,
|
||||
+ .max_segments = 7,
|
||||
+ .max_brightness = 3,
|
||||
+ .max_key_rows = 5,
|
||||
+ .max_key_cols = 7,
|
||||
+ .init = fd655_init,
|
||||
+ .data = fd655_data,
|
||||
+ .keys = tm1650_keys,
|
||||
+};
|
||||
+
|
||||
+static const struct tm16xx_controller fd6551_controller = {
|
||||
+ .max_grids = 5,
|
||||
+ .max_segments = 7,
|
||||
+ .max_brightness = 8,
|
||||
+ .max_key_rows = 0,
|
||||
+ .max_key_cols = 0,
|
||||
+ .init = fd6551_init,
|
||||
+ .data = fd655_data,
|
||||
+};
|
||||
+
|
||||
+static const struct tm16xx_controller hbs658_controller = {
|
||||
+ .max_grids = 5,
|
||||
+ .max_segments = 8,
|
||||
+ .max_brightness = 8,
|
||||
+ .max_key_rows = 1,
|
||||
+ .max_key_cols = 8,
|
||||
+ .init = hbs658_init,
|
||||
+ .data = hbs658_data,
|
||||
+ .keys = hbs658_keys,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id tm16xx_i2c_of_match[] = {
|
||||
+ { .compatible = "titanmec,tm1650", .data = &tm1650_controller },
|
||||
+ { .compatible = "fdhisi,fd6551", .data = &fd6551_controller },
|
||||
+ { .compatible = "fdhisi,fd655", .data = &fd655_controller },
|
||||
+ { .compatible = "winrise,hbs658", .data = &hbs658_controller },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, tm16xx_i2c_of_match);
|
||||
+
|
||||
+static const struct i2c_device_id tm16xx_i2c_id[] = {
|
||||
+ { "tm1650", (kernel_ulong_t)&tm1650_controller },
|
||||
+ { "fd6551", (kernel_ulong_t)&fd6551_controller },
|
||||
+ { "fd655", (kernel_ulong_t)&fd655_controller },
|
||||
+ { "hbs658", (kernel_ulong_t)&hbs658_controller },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(i2c, tm16xx_i2c_id);
|
||||
+
|
||||
+static struct i2c_driver tm16xx_i2c_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "tm16xx-i2c",
|
||||
+ .of_match_table = tm16xx_i2c_of_match,
|
||||
+ },
|
||||
+ .probe = tm16xx_i2c_probe,
|
||||
+ .remove = tm16xx_i2c_remove,
|
||||
+ .shutdown = tm16xx_i2c_remove,
|
||||
+ .id_table = tm16xx_i2c_id,
|
||||
+};
|
||||
+module_i2c_driver(tm16xx_i2c_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Jean-François Lessard");
|
||||
+MODULE_DESCRIPTION("TM16xx-i2c LED Display Controllers");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_IMPORT_NS("TM16XX");
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,484 @@
|
||||
From f9f715779d52d8ae186670e89c140de64d3cc739 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Lessard?= <jefflessard3@gmail.com>
|
||||
Date: Sat, 23 Aug 2025 21:55:14 -0400
|
||||
Subject: [PATCH 51/54] TEST: auxdisplay: TM16xx: Add support for SPI-based
|
||||
controllers
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add support for TM16xx-compatible auxiliary display controllers connected
|
||||
via the SPI bus.
|
||||
|
||||
The implementation includes:
|
||||
- SPI driver registration and initialization
|
||||
- Probe/remove logic for SPI devices
|
||||
- Controller-specific handling and communication sequences
|
||||
- Integration with the TM16xx core driver for common functionality
|
||||
|
||||
This allows platforms using TM16xx or compatible controllers over SPI to be
|
||||
managed by the TM16xx driver infrastructure.
|
||||
|
||||
Signed-off-by: Jean-François Lessard <jefflessard3@gmail.com>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
drivers/auxdisplay/Kconfig | 16 ++
|
||||
drivers/auxdisplay/Makefile | 1 +
|
||||
drivers/auxdisplay/tm16xx_spi.c | 397 ++++++++++++++++++++++++++++++++
|
||||
4 files changed, 415 insertions(+)
|
||||
create mode 100644 drivers/auxdisplay/tm16xx_spi.c
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index f1354b5c9bd7..10fe2e0d8ce6 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -25052,6 +25052,7 @@ F: drivers/auxdisplay/tm16xx.h
|
||||
F: drivers/auxdisplay/tm16xx_core.c
|
||||
F: drivers/auxdisplay/tm16xx_i2c.c
|
||||
F: drivers/auxdisplay/tm16xx_keypad.c
|
||||
+F: drivers/auxdisplay/tm16xx_spi.c
|
||||
|
||||
TMIO/SDHI MMC DRIVER
|
||||
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
|
||||
index d48c2f18950e..61e5af8d0a3d 100644
|
||||
--- a/drivers/auxdisplay/Kconfig
|
||||
+++ b/drivers/auxdisplay/Kconfig
|
||||
@@ -560,6 +560,22 @@ config TM16XX_I2C
|
||||
will be called tm16xx_i2c and you will also get tm16xx for the
|
||||
core module.
|
||||
|
||||
+config TM16XX_SPI
|
||||
+ tristate "TM16XX-compatible SPI 7-segment LED controllers with keyscan"
|
||||
+ depends on SPI
|
||||
+ select TM16XX
|
||||
+ help
|
||||
+ This driver supports the following TM16XX compatible
|
||||
+ SPI (3-wire) 7-segment led display chips:
|
||||
+ - Titanmec: TM1618, TM1620, TM1628, TM1638
|
||||
+ - Fuda Hisi: FD620, FD628
|
||||
+ - i-Core: AiP1618, AiP1628
|
||||
+ - Princeton: PT6964
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called tm16xx_spi and you will also get tm16xx for the
|
||||
+ core module.
|
||||
+
|
||||
#
|
||||
# Character LCD with non-conforming interface section
|
||||
#
|
||||
diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile
|
||||
index ba7b310f5667..2485a3a6769d 100644
|
||||
--- a/drivers/auxdisplay/Makefile
|
||||
+++ b/drivers/auxdisplay/Makefile
|
||||
@@ -20,3 +20,4 @@ obj-$(CONFIG_TM16XX) += tm16xx.o
|
||||
tm16xx-y += tm16xx_core.o
|
||||
tm16xx-$(CONFIG_TM16XX_KEYPAD) += tm16xx_keypad.o
|
||||
obj-$(CONFIG_TM16XX_I2C) += tm16xx_i2c.o
|
||||
+obj-$(CONFIG_TM16XX_SPI) += tm16xx_spi.o
|
||||
diff --git a/drivers/auxdisplay/tm16xx_spi.c b/drivers/auxdisplay/tm16xx_spi.c
|
||||
new file mode 100644
|
||||
index 000000000000..b305301f918c
|
||||
--- /dev/null
|
||||
+++ b/drivers/auxdisplay/tm16xx_spi.c
|
||||
@@ -0,0 +1,397 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * TM16xx and compatible LED display/keypad controller driver
|
||||
+ * Supports TM16xx, FD6xx, PT6964, HBS658, AIP16xx and related chips.
|
||||
+ *
|
||||
+ * Copyright (C) 2025 Jean-François Lessard
|
||||
+ */
|
||||
+
|
||||
+#include <linux/bitfield.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/mod_devicetable.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
+
|
||||
+#include "tm16xx.h"
|
||||
+
|
||||
+#define TM16XX_SPI_BUFFER_SIZE 8
|
||||
+#define TM16XX_SPI_TWAIT_US 2
|
||||
+
|
||||
+static int tm16xx_spi_probe(struct spi_device *spi)
|
||||
+{
|
||||
+ const struct tm16xx_controller *controller;
|
||||
+ struct tm16xx_display *display;
|
||||
+ int ret;
|
||||
+
|
||||
+ controller = spi_get_device_match_data(spi);
|
||||
+ if (!controller)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ display = devm_kzalloc(&spi->dev, sizeof(*display), GFP_KERNEL);
|
||||
+ if (!display)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* Allocate DMA-safe buffer */
|
||||
+ display->spi_buffer = devm_kzalloc(&spi->dev, TM16XX_SPI_BUFFER_SIZE, GFP_KERNEL);
|
||||
+ if (!display->spi_buffer)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ display->dev = &spi->dev;
|
||||
+ display->controller = controller;
|
||||
+
|
||||
+ spi_set_drvdata(spi, display);
|
||||
+
|
||||
+ ret = tm16xx_probe(display);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void tm16xx_spi_remove(struct spi_device *spi)
|
||||
+{
|
||||
+ struct tm16xx_display *display = spi_get_drvdata(spi);
|
||||
+
|
||||
+ tm16xx_remove(display);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_spi_read() - SPI read helper for controller
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ * @cmd: command to send
|
||||
+ * @cmd_len: length of command
|
||||
+ * @data: buffer for received data
|
||||
+ * @data_len: length of data to read
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure
|
||||
+ */
|
||||
+static int tm16xx_spi_read(struct tm16xx_display *display, u8 *cmd,
|
||||
+ size_t cmd_len, u8 *data, size_t data_len)
|
||||
+{
|
||||
+ struct spi_device *spi = to_spi_device(display->dev);
|
||||
+ struct spi_message msg;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* If STB is high during transmission, command is invalid.
|
||||
+ * Reading requires a minimum 2 microseconds wait (Twait)
|
||||
+ * after the 8th CLK rising edge before reading on falling edge.
|
||||
+ */
|
||||
+ struct spi_transfer xfers[2] = {
|
||||
+ {
|
||||
+ .tx_buf = cmd,
|
||||
+ .len = cmd_len,
|
||||
+ .cs_change = 0, /* NO CS toggle */
|
||||
+ .delay.value = TM16XX_SPI_TWAIT_US,
|
||||
+ .delay.unit = SPI_DELAY_UNIT_USECS,
|
||||
+ }, {
|
||||
+ .rx_buf = data,
|
||||
+ .len = data_len,
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ spi_message_init_with_transfers(&msg, xfers, ARRAY_SIZE(xfers));
|
||||
+
|
||||
+ ret = spi_sync(spi, &msg);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * tm16xx_spi_write() - SPI write helper for controller
|
||||
+ * @display: pointer to tm16xx_display
|
||||
+ * @data: data to write
|
||||
+ * @len: number of bytes to write
|
||||
+ *
|
||||
+ * Return: 0 on success, negative error code on failure
|
||||
+ */
|
||||
+static int tm16xx_spi_write(struct tm16xx_display *display, u8 *data, size_t len)
|
||||
+{
|
||||
+ struct spi_device *spi = to_spi_device(display->dev);
|
||||
+
|
||||
+ return spi_write(spi, data, len);
|
||||
+}
|
||||
+
|
||||
+/* SPI controller-specific functions */
|
||||
+static int tm1628_init(struct tm16xx_display *display)
|
||||
+{
|
||||
+ const enum led_brightness brightness = display->main_led.brightness;
|
||||
+ const u8 num_hwgrid = display->num_hwgrid;
|
||||
+ u8 *cmd = display->spi_buffer;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Set mode command based on grid count */
|
||||
+ cmd[0] = TM16XX_CMD_MODE;
|
||||
+ if (num_hwgrid <= 4)
|
||||
+ cmd[0] |= TM16XX_MODE_4GRIDS;
|
||||
+ else if (num_hwgrid == 5)
|
||||
+ cmd[0] |= TM16XX_MODE_5GRIDS;
|
||||
+ else if (num_hwgrid == 6)
|
||||
+ cmd[0] |= TM16XX_MODE_6GRIDS;
|
||||
+ else
|
||||
+ cmd[0] |= TM16XX_MODE_7GRIDS;
|
||||
+
|
||||
+ ret = tm16xx_spi_write(display, cmd, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Set data command */
|
||||
+ cmd[0] = TM16XX_CMD_WRITE | TM16XX_DATA_ADDR_AUTO;
|
||||
+ ret = tm16xx_spi_write(display, cmd, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Set control command with brightness */
|
||||
+ cmd[0] = TM16XX_CMD_CTRL |
|
||||
+ TM16XX_CTRL_BRIGHTNESS(brightness, brightness - 1, TM16XX);
|
||||
+ ret = tm16xx_spi_write(display, cmd, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tm1618_data(struct tm16xx_display *display, u8 index,
|
||||
+ unsigned int grid)
|
||||
+{
|
||||
+ u8 *cmd = display->spi_buffer;
|
||||
+
|
||||
+ cmd[0] = TM16XX_CMD_ADDR + index * 2;
|
||||
+ cmd[1] = FIELD_GET(TM1618_BYTE1_MASK, grid);
|
||||
+ cmd[2] = FIELD_GET(TM1618_BYTE2_MASK, grid) << TM1618_BYTE2_SHIFT;
|
||||
+
|
||||
+ return tm16xx_spi_write(display, cmd, 3);
|
||||
+}
|
||||
+
|
||||
+static int tm1628_data(struct tm16xx_display *display, u8 index,
|
||||
+ unsigned int grid)
|
||||
+{
|
||||
+ u8 *cmd = display->spi_buffer;
|
||||
+
|
||||
+ cmd[0] = TM16XX_CMD_ADDR + index * 2;
|
||||
+ cmd[1] = FIELD_GET(TM1628_BYTE1_MASK, grid);
|
||||
+ cmd[2] = FIELD_GET(TM1628_BYTE2_MASK, grid);
|
||||
+
|
||||
+ return tm16xx_spi_write(display, cmd, 3);
|
||||
+}
|
||||
+
|
||||
+static int tm1628_keys(struct tm16xx_display *display)
|
||||
+{
|
||||
+ u8 *cmd = display->spi_buffer;
|
||||
+ u8 *codes = display->spi_buffer;
|
||||
+ unsigned int i;
|
||||
+ int bit, byte;
|
||||
+ bool value;
|
||||
+ int ret;
|
||||
+
|
||||
+ cmd[0] = TM16XX_CMD_READ;
|
||||
+ ret = tm16xx_spi_read(display, cmd, 1, codes, TM1628_KEY_READ_LEN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* prevent false readings */
|
||||
+ for (i = 0; i < TM1628_KEY_READ_LEN; i++) {
|
||||
+ if (codes[i] & ~TM1628_KEY_MASK)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ tm16xx_for_each_key(display, row, col) {
|
||||
+ byte = col >> 1;
|
||||
+ bit = row + ((col & 1) * 3);
|
||||
+ value = !!(codes[byte] & BIT(bit));
|
||||
+
|
||||
+ tm16xx_set_key(display, row, col, value);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tm1638_keys(struct tm16xx_display *display)
|
||||
+{
|
||||
+ u8 *cmd = display->spi_buffer;
|
||||
+ u8 *codes = display->spi_buffer;
|
||||
+ unsigned int i;
|
||||
+ int bit, byte;
|
||||
+ bool value;
|
||||
+ int ret;
|
||||
+
|
||||
+ cmd[0] = TM16XX_CMD_READ;
|
||||
+ ret = tm16xx_spi_read(display, cmd, 1, codes, TM1638_KEY_READ_LEN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* prevent false readings */
|
||||
+ for (i = 0; i < TM1638_KEY_READ_LEN; i++) {
|
||||
+ if (codes[i] & ~TM1638_KEY_MASK)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ tm16xx_for_each_key(display, row, col) {
|
||||
+ byte = col >> 1;
|
||||
+ bit = (2 - row) + ((col & 1) << 2);
|
||||
+ value = !!(codes[byte] & BIT(bit));
|
||||
+
|
||||
+ tm16xx_set_key(display, row, col, value);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int tm1618_keys(struct tm16xx_display *display)
|
||||
+{
|
||||
+ u8 *cmd = display->spi_buffer;
|
||||
+ u8 *codes = display->spi_buffer;
|
||||
+ unsigned int i;
|
||||
+ int ret;
|
||||
+
|
||||
+ cmd[0] = TM16XX_CMD_READ;
|
||||
+ ret = tm16xx_spi_read(display, cmd, 1, codes, TM1618_KEY_READ_LEN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* prevent false readings */
|
||||
+ for (i = 0; i < TM1618_KEY_READ_LEN; i++) {
|
||||
+ if (codes[i] & ~TM1618_KEY_MASK)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ tm16xx_set_key(display, 0, 0, !!(codes[0] & BIT(1)));
|
||||
+ tm16xx_set_key(display, 0, 1, !!(codes[0] & BIT(4)));
|
||||
+ tm16xx_set_key(display, 0, 2, !!(codes[1] & BIT(1)));
|
||||
+ tm16xx_set_key(display, 0, 3, !!(codes[1] & BIT(4)));
|
||||
+ tm16xx_set_key(display, 0, 4, !!(codes[2] & BIT(1)));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int fd620_data(struct tm16xx_display *display, u8 index,
|
||||
+ unsigned int grid)
|
||||
+{
|
||||
+ u8 *cmd = display->spi_buffer;
|
||||
+
|
||||
+ cmd[0] = TM16XX_CMD_ADDR + index * 2;
|
||||
+ cmd[1] = FIELD_GET(FD620_BYTE1_MASK, grid);
|
||||
+ cmd[2] = FIELD_GET(FD620_BYTE2_MASK, grid) << FD620_BYTE2_SHIFT;
|
||||
+
|
||||
+ return tm16xx_spi_write(display, cmd, 3);
|
||||
+}
|
||||
+
|
||||
+static int fd620_keys(struct tm16xx_display *display)
|
||||
+{
|
||||
+ u8 *cmd = display->spi_buffer;
|
||||
+ u8 *codes = display->spi_buffer;
|
||||
+ unsigned int i;
|
||||
+ int ret;
|
||||
+
|
||||
+ cmd[0] = TM16XX_CMD_READ;
|
||||
+ ret = tm16xx_spi_read(display, cmd, 1, codes, FD620_KEY_READ_LEN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* prevent false readings */
|
||||
+ for (i = 0; i < FD620_KEY_READ_LEN; i++) {
|
||||
+ if (codes[i] & ~FD620_KEY_MASK)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ tm16xx_set_key(display, 0, 0, codes[0] & BIT(0));
|
||||
+ tm16xx_set_key(display, 0, 1, codes[0] & BIT(3));
|
||||
+ tm16xx_set_key(display, 0, 2, codes[1] & BIT(0));
|
||||
+ tm16xx_set_key(display, 0, 3, codes[1] & BIT(3));
|
||||
+ tm16xx_set_key(display, 0, 4, codes[2] & BIT(0));
|
||||
+ tm16xx_set_key(display, 0, 5, codes[2] & BIT(3));
|
||||
+ tm16xx_set_key(display, 0, 6, codes[3] & BIT(0));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* SPI controller definitions */
|
||||
+static const struct tm16xx_controller tm1618_controller = {
|
||||
+ .max_grids = 7,
|
||||
+ .max_segments = 8,
|
||||
+ .max_brightness = 8,
|
||||
+ .max_key_rows = 1,
|
||||
+ .max_key_cols = 5,
|
||||
+ .init = tm1628_init,
|
||||
+ .data = tm1618_data,
|
||||
+ .keys = tm1618_keys,
|
||||
+};
|
||||
+
|
||||
+static const struct tm16xx_controller tm1620_controller = {
|
||||
+ .max_grids = 6,
|
||||
+ .max_segments = 10,
|
||||
+ .max_brightness = 8,
|
||||
+ .max_key_rows = 0,
|
||||
+ .max_key_cols = 0,
|
||||
+ .init = tm1628_init,
|
||||
+ .data = tm1628_data,
|
||||
+};
|
||||
+
|
||||
+static const struct tm16xx_controller tm1628_controller = {
|
||||
+ .max_grids = 7,
|
||||
+ .max_segments = 14, /* seg 11 unused */
|
||||
+ .max_brightness = 8,
|
||||
+ .max_key_rows = 2,
|
||||
+ .max_key_cols = 10,
|
||||
+ .init = tm1628_init,
|
||||
+ .data = tm1628_data,
|
||||
+ .keys = tm1628_keys,
|
||||
+};
|
||||
+
|
||||
+static const struct tm16xx_controller tm1638_controller = {
|
||||
+ .max_grids = 8,
|
||||
+ .max_segments = 10,
|
||||
+ .max_brightness = 8,
|
||||
+ .max_key_rows = 3,
|
||||
+ .max_key_cols = 8,
|
||||
+ .init = tm1628_init,
|
||||
+ .data = tm1628_data,
|
||||
+ .keys = tm1638_keys,
|
||||
+};
|
||||
+
|
||||
+static const struct tm16xx_controller fd620_controller = {
|
||||
+ .max_grids = 5,
|
||||
+ .max_segments = 8,
|
||||
+ .max_brightness = 8,
|
||||
+ .max_key_rows = 1,
|
||||
+ .max_key_cols = 7,
|
||||
+ .init = tm1628_init,
|
||||
+ .data = fd620_data,
|
||||
+ .keys = fd620_keys,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id tm16xx_spi_of_match[] = {
|
||||
+ { .compatible = "titanmec,tm1618", .data = &tm1618_controller },
|
||||
+ { .compatible = "titanmec,tm1620", .data = &tm1620_controller },
|
||||
+ { .compatible = "titanmec,tm1628", .data = &tm1628_controller },
|
||||
+ { .compatible = "titanmec,tm1638", .data = &tm1638_controller },
|
||||
+ { .compatible = "fdhisi,fd620", .data = &fd620_controller },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, tm16xx_spi_of_match);
|
||||
+
|
||||
+static const struct spi_device_id tm16xx_spi_id[] = {
|
||||
+ { "tm1618", (kernel_ulong_t)&tm1618_controller },
|
||||
+ { "tm1620", (kernel_ulong_t)&tm1620_controller },
|
||||
+ { "tm1628", (kernel_ulong_t)&tm1628_controller },
|
||||
+ { "tm1638", (kernel_ulong_t)&tm1638_controller },
|
||||
+ { "fd620", (kernel_ulong_t)&fd620_controller },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(spi, tm16xx_spi_id);
|
||||
+
|
||||
+static struct spi_driver tm16xx_spi_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "tm16xx-spi",
|
||||
+ .of_match_table = tm16xx_spi_of_match,
|
||||
+ },
|
||||
+ .probe = tm16xx_spi_probe,
|
||||
+ .remove = tm16xx_spi_remove,
|
||||
+ .shutdown = tm16xx_spi_remove,
|
||||
+ .id_table = tm16xx_spi_id,
|
||||
+};
|
||||
+module_spi_driver(tm16xx_spi_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Jean-François Lessard");
|
||||
+MODULE_DESCRIPTION("TM16xx-spi LED Display Controllers");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_IMPORT_NS("TM16XX");
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
From f660e55ee33d8e475ab949b8cf161f7deca08b60 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Wed, 11 Jun 2025 11:23:44 +0000
|
||||
Subject: [PATCH 52/54] WIP: arm64: dts: meson-gxl-s905w-tx3-mini: support the
|
||||
fd628 display
|
||||
|
||||
The TX3-mini has an FD628 display. Add support using the tm166xx
|
||||
kernel driver and userspace tools [0].
|
||||
|
||||
[0] https://github.com/jefflessard/tm16xx-display
|
||||
|
||||
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
|
||||
---
|
||||
.../dts/amlogic/meson-gxl-s905w-tx3-mini.dts | 98 +++++++++++++++++++
|
||||
1 file changed, 98 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
|
||||
index 6705c2082a78..fec1b3fa0467 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
#include "meson-gxl-s905x.dtsi"
|
||||
#include "meson-gx-p23x-q20x.dtsi"
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/leds/common.h>
|
||||
|
||||
/ {
|
||||
compatible = "oranth,tx3-mini", "amlogic,s905w", "amlogic,meson-gxl";
|
||||
@@ -19,6 +21,102 @@ memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x0 0x0 0x40000000>; /* 1 GiB or 2 GiB */
|
||||
};
|
||||
+
|
||||
+ display_client: spi {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ compatible = "spi-gpio";
|
||||
+ sck-gpios = <&gpio 76 GPIO_ACTIVE_HIGH>;
|
||||
+ mosi-gpios = <&gpio 75 GPIO_ACTIVE_HIGH>;
|
||||
+ cs-gpios = <&gpio_ao 4 GPIO_ACTIVE_LOW>;
|
||||
+ num-chipselects = <1>;
|
||||
+
|
||||
+ display@0 {
|
||||
+ compatible = "fdhisi,fd628", "titanmec,tm1628";
|
||||
+ reg = <0>;
|
||||
+ spi-3wire;
|
||||
+ spi-lsb-first;
|
||||
+ spi-max-frequency = <500000>;
|
||||
+
|
||||
+ digits {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ digit@0 {
|
||||
+ reg = <0>;
|
||||
+ segments = <3 3>,
|
||||
+ <3 4>,
|
||||
+ <3 5>,
|
||||
+ <3 0>,
|
||||
+ <3 1>,
|
||||
+ <3 2>,
|
||||
+ <3 6>;
|
||||
+ };
|
||||
+ digit@1 {
|
||||
+ reg = <1>;
|
||||
+ segments = <2 3>,
|
||||
+ <2 4>,
|
||||
+ <2 5>,
|
||||
+ <2 0>,
|
||||
+ <2 1>,
|
||||
+ <2 2>,
|
||||
+ <2 6>;
|
||||
+ };
|
||||
+ digit@2 {
|
||||
+ reg = <2>;
|
||||
+ segments = <1 3>,
|
||||
+ <1 4>,
|
||||
+ <1 5>,
|
||||
+ <1 0>,
|
||||
+ <1 1>,
|
||||
+ <1 2>,
|
||||
+ <1 6>;
|
||||
+ };
|
||||
+ digit@3 {
|
||||
+ reg = <3>;
|
||||
+ segments = <0 3>,
|
||||
+ <0 4>,
|
||||
+ <0 5>,
|
||||
+ <0 0>,
|
||||
+ <0 1>,
|
||||
+ <0 2>,
|
||||
+ <0 6>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+ led@4,0 {
|
||||
+ reg = <4 0>;
|
||||
+ function = LED_FUNCTION_ALARM;
|
||||
+ };
|
||||
+ led@4,1 {
|
||||
+ reg = <4 1>;
|
||||
+ function = LED_FUNCTION_USB;
|
||||
+ };
|
||||
+ led@4,3 {
|
||||
+ reg = <4 3>;
|
||||
+ function = "pause";
|
||||
+ };
|
||||
+ led@4,2 {
|
||||
+ reg = <4 2>;
|
||||
+ function = "play";
|
||||
+ };
|
||||
+ led@4,4 {
|
||||
+ reg = <4 4>;
|
||||
+ function = "colon";
|
||||
+ };
|
||||
+ led@4,5 {
|
||||
+ reg = <4 5>;
|
||||
+ function = LED_FUNCTION_LAN;
|
||||
+ };
|
||||
+ led@4,6 {
|
||||
+ reg = <4 6>;
|
||||
+ function = LED_FUNCTION_WLAN;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&ir {
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
From 43fdd7d9ddd536d158909fece282aee5a85c4867 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Thu, 9 Feb 2023 10:11:39 +0000
|
||||
Subject: [PATCH 53/54] WIP: arm64: dts: meson-gxm-tx9-pro: support the fd628
|
||||
display
|
||||
|
||||
The TX9-Pro has an FD628 display. Add support using the tm166xx
|
||||
kernel driver and userspace tools [0].
|
||||
|
||||
[0] https://github.com/jefflessard/tm16xx-display
|
||||
|
||||
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
|
||||
---
|
||||
.../boot/dts/amlogic/meson-gxm-tx9-pro.dts | 97 +++++++++++++++++++
|
||||
1 file changed, 97 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts
|
||||
index 9a62176cfe5a..cf16995ebf5e 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-tx9-pro.dts
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "meson-gxm.dtsi"
|
||||
#include "meson-gx-p23x-q20x.dtsi"
|
||||
#include <dt-bindings/input/input.h>
|
||||
+#include <dt-bindings/leds/common.h>
|
||||
|
||||
/ {
|
||||
compatible = "oranth,tx9-pro", "amlogic,s912", "amlogic,meson-gxm";
|
||||
@@ -37,6 +38,102 @@ button {
|
||||
gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
+
|
||||
+ display_client: spi {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ compatible = "spi-gpio";
|
||||
+ sck-gpios = <&gpio 76 GPIO_ACTIVE_HIGH>;
|
||||
+ mosi-gpios = <&gpio 75 GPIO_ACTIVE_HIGH>;
|
||||
+ cs-gpios = <&gpio 53 GPIO_ACTIVE_LOW>;
|
||||
+ num-chipselects = <1>;
|
||||
+
|
||||
+ display@0 {
|
||||
+ compatible = "fdhisi,fd628", "titanmec,tm1628";
|
||||
+ reg = <0>;
|
||||
+ spi-3wire;
|
||||
+ spi-lsb-first;
|
||||
+ spi-max-frequency = <500000>;
|
||||
+
|
||||
+ digits {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ digit@0 {
|
||||
+ reg = <0>;
|
||||
+ segments = <0 3>,
|
||||
+ <0 1>,
|
||||
+ <0 2>,
|
||||
+ <0 6>,
|
||||
+ <0 4>,
|
||||
+ <0 5>,
|
||||
+ <0 0>;
|
||||
+ };
|
||||
+ digit@1 {
|
||||
+ reg = <1>;
|
||||
+ segments = <1 3>,
|
||||
+ <1 1>,
|
||||
+ <1 2>,
|
||||
+ <1 6>,
|
||||
+ <1 4>,
|
||||
+ <1 5>,
|
||||
+ <1 0>;
|
||||
+ };
|
||||
+ digit@2 {
|
||||
+ reg = <2>;
|
||||
+ segments = <2 3>,
|
||||
+ <2 1>,
|
||||
+ <2 2>,
|
||||
+ <2 6>,
|
||||
+ <2 4>,
|
||||
+ <2 5>,
|
||||
+ <2 0>;
|
||||
+ };
|
||||
+ digit@3 {
|
||||
+ reg = <3>;
|
||||
+ segments = <3 3>,
|
||||
+ <3 1>,
|
||||
+ <3 2>,
|
||||
+ <3 6>,
|
||||
+ <3 4>,
|
||||
+ <3 5>,
|
||||
+ <3 0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+ led@4,0 {
|
||||
+ reg = <4 0>;
|
||||
+ function = LED_FUNCTION_ALARM;
|
||||
+ };
|
||||
+ led@4,1 {
|
||||
+ reg = <4 1>;
|
||||
+ function = LED_FUNCTION_USB;
|
||||
+ };
|
||||
+ led@4,2 {
|
||||
+ reg = <4 2>;
|
||||
+ function = "play";
|
||||
+ };
|
||||
+ led@4,3 {
|
||||
+ reg = <4 3>;
|
||||
+ function = "pause";
|
||||
+ };
|
||||
+ led@4,4 {
|
||||
+ reg = <4 4>;
|
||||
+ function = "colon";
|
||||
+ };
|
||||
+ led@4,5 {
|
||||
+ reg = <4 5>;
|
||||
+ function = LED_FUNCTION_LAN;
|
||||
+ };
|
||||
+ led@4,6 {
|
||||
+ reg = <4 6>;
|
||||
+ function = LED_FUNCTION_WLAN;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
ðmac {
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
From 4264c7df80fd5603bf7789870dce5a94db6469c2 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hewitt <christianshewitt@gmail.com>
|
||||
Date: Wed, 11 Jun 2025 11:47:31 +0000
|
||||
Subject: [PATCH 54/54] WIP: arm64: dts: meson-g12a-x96-max: support the fd628
|
||||
display
|
||||
|
||||
The X96-Max has an FD628 display. Add support using the tm166xx
|
||||
kernel driver and userspace tools [0].
|
||||
|
||||
[0] https://github.com/jefflessard/tm16xx-display
|
||||
|
||||
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
|
||||
---
|
||||
.../boot/dts/amlogic/meson-g12a-x96-max.dts | 101 ++++++++++++++++++
|
||||
1 file changed, 101 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
|
||||
index 5ab460a3e637..a4712edc380f 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "meson-g12a.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
+#include <dt-bindings/leds/common.h>
|
||||
#include <dt-bindings/gpio/meson-g12a-gpio.h>
|
||||
#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
|
||||
|
||||
@@ -54,6 +55,106 @@ hdmi_connector_in: endpoint {
|
||||
};
|
||||
};
|
||||
|
||||
+ display_client: spi {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ compatible = "spi-gpio";
|
||||
+ sck-gpios = <&gpio 64 GPIO_ACTIVE_HIGH>;
|
||||
+ mosi-gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
|
||||
+ cs-gpios = <&gpio_ao 10 GPIO_ACTIVE_LOW>;
|
||||
+ num-chipselects = <1>;
|
||||
+
|
||||
+ display@0 {
|
||||
+ compatible = "fdhisi,fd628", "titanmec,tm1628";
|
||||
+ reg = <0>;
|
||||
+ spi-3wire;
|
||||
+ spi-lsb-first;
|
||||
+ spi-max-frequency = <500000>;
|
||||
+
|
||||
+ digits {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ digit@0 {
|
||||
+ reg = <0>;
|
||||
+ segments = <0 7>,
|
||||
+ <1 7>,
|
||||
+ <2 7>,
|
||||
+ <3 7>,
|
||||
+ <4 7>,
|
||||
+ <5 7>,
|
||||
+ <6 7>;
|
||||
+ };
|
||||
+
|
||||
+ digit@1 {
|
||||
+ reg = <1>;
|
||||
+ segments = <0 6>,
|
||||
+ <1 6>,
|
||||
+ <2 6>,
|
||||
+ <3 6>,
|
||||
+ <4 6>,
|
||||
+ <5 6>,
|
||||
+ <6 6>;
|
||||
+ };
|
||||
+
|
||||
+ digit@2 {
|
||||
+ reg = <2>;
|
||||
+ segments = <0 5>,
|
||||
+ <1 5>,
|
||||
+ <2 5>,
|
||||
+ <3 5>,
|
||||
+ <4 5>,
|
||||
+ <5 5>,
|
||||
+ <6 5>;
|
||||
+ };
|
||||
+
|
||||
+ digit@3 {
|
||||
+ reg = <3>;
|
||||
+ segments = <0 4>,
|
||||
+ <1 4>,
|
||||
+ <2 4>,
|
||||
+ <3 4>,
|
||||
+ <4 4>,
|
||||
+ <5 4>,
|
||||
+ <6 4>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <0>;
|
||||
+ led@0,3 {
|
||||
+ reg = <0 3>;
|
||||
+ function = "apps";
|
||||
+ };
|
||||
+ led@1,3 {
|
||||
+ reg = <1 3>;
|
||||
+ function = "setup";
|
||||
+ };
|
||||
+ led@2,3 {
|
||||
+ reg = <2 3>;
|
||||
+ function = LED_FUNCTION_USB;
|
||||
+ };
|
||||
+ led@3,3 {
|
||||
+ reg = <3 3>;
|
||||
+ function = LED_FUNCTION_SD;
|
||||
+ };
|
||||
+ led@4,3 {
|
||||
+ reg = <4 3>;
|
||||
+ function = "colon";
|
||||
+ };
|
||||
+ led@5,3 {
|
||||
+ reg = <5 3>;
|
||||
+ function = "hd";
|
||||
+ };
|
||||
+ led@6,3 {
|
||||
+ reg = <6 3>;
|
||||
+ function = "cvbs";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
emmc_pwrseq: emmc-pwrseq {
|
||||
compatible = "mmc-pwrseq-emmc";
|
||||
reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/arm64 6.16.0-rc3 Kernel Configuration
|
||||
# Linux/arm64 6.16.5 Kernel Configuration
|
||||
#
|
||||
CONFIG_CC_VERSION_TEXT="aarch64-libreelec-linux-gnu-gcc-15.1.0 (GCC) 15.1.0"
|
||||
CONFIG_CC_VERSION_TEXT="aarch64-libreelec-linux-gnu-gcc-15.2.0 (GCC) 15.2.0"
|
||||
CONFIG_CC_IS_GCC=y
|
||||
CONFIG_GCC_VERSION=150100
|
||||
CONFIG_GCC_VERSION=150200
|
||||
CONFIG_CLANG_VERSION=0
|
||||
CONFIG_AS_IS_GNU=y
|
||||
CONFIG_AS_VERSION=24400
|
||||
@@ -233,7 +233,6 @@ CONFIG_ELF_CORE=y
|
||||
# CONFIG_BASE_SMALL is not set
|
||||
CONFIG_FUTEX=y
|
||||
CONFIG_FUTEX_PI=y
|
||||
CONFIG_FUTEX_PRIVATE_HASH=y
|
||||
CONFIG_EPOLL=y
|
||||
CONFIG_SIGNALFD=y
|
||||
CONFIG_TIMERFD=y
|
||||
@@ -984,7 +983,6 @@ CONFIG_ARCH_HAS_PTE_DEVMAP=y
|
||||
CONFIG_ARCH_HAS_ZONE_DMA_SET=y
|
||||
CONFIG_ZONE_DMA=y
|
||||
CONFIG_ZONE_DMA32=y
|
||||
CONFIG_VMAP_PFN=y
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
# CONFIG_PERCPU_STATS is not set
|
||||
# CONFIG_GUP_TEST is not set
|
||||
@@ -2743,7 +2741,7 @@ CONFIG_INPUT=y
|
||||
CONFIG_INPUT_LEDS=y
|
||||
CONFIG_INPUT_FF_MEMLESS=y
|
||||
# CONFIG_INPUT_SPARSEKMAP is not set
|
||||
# CONFIG_INPUT_MATRIXKMAP is not set
|
||||
CONFIG_INPUT_MATRIXKMAP=y
|
||||
|
||||
#
|
||||
# Userland interfaces
|
||||
@@ -3040,6 +3038,7 @@ CONFIG_I2C_ALGOBIT=y
|
||||
# CONFIG_I2C_AMD8111 is not set
|
||||
# CONFIG_I2C_I801 is not set
|
||||
# CONFIG_I2C_ISCH is not set
|
||||
# CONFIG_I2C_PIIX4 is not set
|
||||
# CONFIG_I2C_NFORCE2 is not set
|
||||
# CONFIG_I2C_NVIDIA_GPU is not set
|
||||
# CONFIG_I2C_SIS5595 is not set
|
||||
@@ -3306,7 +3305,6 @@ CONFIG_POWER_RESET_GPIO_RESTART=y
|
||||
# CONFIG_POWER_RESET_LTC2952 is not set
|
||||
CONFIG_POWER_RESET_REGULATOR=y
|
||||
CONFIG_POWER_RESET_RESTART=y
|
||||
# CONFIG_POWER_RESET_TORADEX_EC is not set
|
||||
# CONFIG_POWER_RESET_XGENE is not set
|
||||
CONFIG_POWER_RESET_SYSCON=y
|
||||
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
|
||||
@@ -4577,13 +4575,20 @@ CONFIG_VIDEO=y
|
||||
CONFIG_AUXDISPLAY=y
|
||||
# CONFIG_HD44780 is not set
|
||||
# CONFIG_LCD2S is not set
|
||||
CONFIG_PANEL_CHANGE_MESSAGE=y
|
||||
CONFIG_PANEL_BOOT_MESSAGE=" HELLO"
|
||||
# CONFIG_CHARLCD_BL_OFF is not set
|
||||
# CONFIG_CHARLCD_BL_ON is not set
|
||||
CONFIG_CHARLCD_BL_FLASH=y
|
||||
CONFIG_LINEDISP=y
|
||||
# CONFIG_IMG_ASCII_LCD is not set
|
||||
# CONFIG_HT16K33 is not set
|
||||
# CONFIG_MAX6959 is not set
|
||||
# CONFIG_SEG_LED_GPIO is not set
|
||||
CONFIG_TM16XX=y
|
||||
CONFIG_TM16XX_KEYPAD=y
|
||||
CONFIG_TM16XX_I2C=y
|
||||
CONFIG_TM16XX_SPI=y
|
||||
CONFIG_DRM=y
|
||||
|
||||
#
|
||||
|
||||
@@ -67,10 +67,13 @@
|
||||
ADDITIONAL_DRIVERS+=""
|
||||
|
||||
# additional packages to install:
|
||||
ADDITIONAL_PACKAGES+=" dtc ethmactool emmctool flashrom pciutils tm16xx"
|
||||
ADDITIONAL_PACKAGES+=" dtc ethmactool emmctool flashrom pciutils"
|
||||
|
||||
# use the kernel CEC framework for libcec (yes / no)
|
||||
CEC_FRAMEWORK_SUPPORT="yes"
|
||||
|
||||
# debug tty path
|
||||
DEBUG_TTY="/dev/ttyAML0"
|
||||
|
||||
# vfd pannel display support
|
||||
VFD_SUPPORT="yes"
|
||||
|
||||
Reference in New Issue
Block a user