RK3326: support the R36T Max internal SDIO WiFi (rk912/rk915)

Users reported the R36T Max clone does not even scan for networks on the
2.0 clone image while the stock OS and Aurknix work (bug report 2). The
R36T Max internal WiFi is an rk912/rk915 SDIO module, which the clone
image had no driver, no DTS wiring and no SDIO quirks for. Port the
working support from ROCKNIX/Aurknix:

- rk915 driver package (AveyondFly/rk915, WiFi/BT SDIO), added to
  ADDITIONAL_DRIVERS.
- 024-mainline-linux-hacks-for-rk915.patch: MMC_CAP2_WIFI_RK912 cap
  behind the supports-rk912 DT property; bypasses the SDIO CIS size
  check and power cycling that break this module's initialization.
- rk3326-aislpc-r36tmax.dts: dedicated device tree (sdio_pwrseq, sdio
  node with supports-rk912, correct joypad wiring including the analog
  stick inversion users hit on the generic clone DTB). Adapted to the
  archr-singleadc-joypad and archr,generic-dsi compatibles.
- Temperature sensor quirk for the "AISLPC R36TMax" model string.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Douglas Teles
2026-07-01 20:01:01 -03:00
parent 9ff72420c6
commit a738af646b
5 changed files with 1092 additions and 1 deletions
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -61,7 +61,7 @@
# for a list of additional drivers see packages/linux-drivers
# Space separated list is supported,
# e.g. ADDITIONAL_DRIVERS="DRIVER1 DRIVER2"
ADDITIONAL_DRIVERS="RTL8188EUS RTL8812AU RTL8814AU RTL8821AU RTL8821CU RTL88x2BU RTL8831 AIC8800 mali-bifrost"
ADDITIONAL_DRIVERS="rk915 RTL8188EUS RTL8812AU RTL8814AU RTL8821AU RTL8821CU RTL88x2BU RTL8831 AIC8800 mali-bifrost"
# Additional Firmware to use ( )
# Space separated list is supported,
@@ -0,0 +1,81 @@
diff -ur linux-6.12.29/drivers/mmc/core/host.c linux_for_rk915/drivers/mmc/core/host.c
--- linux-6.12.29/drivers/mmc/core/host.c 2025-05-18 06:25:00.000000000 +0000
+++ linux_for_rk915/drivers/mmc/core/host.c 2025-06-28 17:43:59.825733795 +0000
@@ -403,6 +403,8 @@
host->caps2 |= MMC_CAP2_NO_SD;
if (device_property_read_bool(dev, "no-mmc"))
host->caps2 |= MMC_CAP2_NO_MMC;
+ if (device_property_read_bool(dev, "supports-rk912"))
+ host->caps2 |= MMC_CAP2_WIFI_RK912;
if (device_property_read_bool(dev, "no-mmc-hs400"))
host->caps2 &= ~(MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V |
MMC_CAP2_HS400_ES);
diff -ur linux-6.12.29/drivers/mmc/core/sdio.c linux_for_rk915/drivers/mmc/core/sdio.c
--- linux-6.12.29/drivers/mmc/core/sdio.c 2025-05-18 06:25:00.000000000 +0000
+++ linux_for_rk915/drivers/mmc/core/sdio.c 2025-06-28 17:43:59.827733748 +0000
@@ -1076,7 +1076,8 @@
* removable card is checked from a detect work later on in the resume
* process.
*/
- if (!mmc_card_keep_power(host)) {
+ if (!mmc_card_keep_power(host) &&
+ !(host->caps2 & MMC_CAP2_WIFI_RK912)) {
mmc_power_up(host, host->card->ocr);
/*
* Tell runtime PM core we just powered up the card,
diff -ur linux-6.12.29/drivers/mmc/core/sdio_cis.c linux_for_rk915/drivers/mmc/core/sdio_cis.c
--- linux-6.12.29/drivers/mmc/core/sdio_cis.c 2025-05-18 06:25:00.000000000 +0000
+++ linux_for_rk915/drivers/mmc/core/sdio_cis.c 2025-06-28 17:43:59.826733772 +0000
@@ -190,15 +191,15 @@
pr_warn("%s: card has broken SDIO 1.1 CIS, forcing SDIO 1.0\n",
mmc_hostname(card->host));
vsn = SDIO_SDIO_REV_1_00;
- } else if (size < min_size) {
+ } else if (size < min_size && !(card->host->caps2 & MMC_CAP2_WIFI_RK912)) {
return -EINVAL;
}
/* TPLFE_MAX_BLK_SIZE */
func->max_blksize = buf[12] | (buf[13] << 8);
/* TPLFE_ENABLE_TIMEOUT_VAL, present in ver 1.1 and above */
- if (vsn > SDIO_SDIO_REV_1_00)
+ if (vsn > SDIO_SDIO_REV_1_00 && !(card->host->caps2 & MMC_CAP2_WIFI_RK912))
func->enable_timeout = (buf[28] | (buf[29] << 8)) * 10;
else
func->enable_timeout = jiffies_to_msecs(HZ);
diff -ur linux-6.12.29/drivers/mmc/host/dw_mmc.c linux_for_rk915/drivers/mmc/host/dw_mmc.c
--- linux-6.12.29/drivers/mmc/host/dw_mmc.c 2025-05-18 06:25:00.000000000 +0000
+++ linux_for_rk915/drivers/mmc/host/dw_mmc.c 2025-06-28 17:44:02.417672518 +0000
@@ -295,6 +295,10 @@
SDMMC_CMD_PRV_DAT_WAIT, 0);
}
+ if ((mmc->caps2 & MMC_CAP2_WIFI_RK912) &&
+ (cmd->opcode == SD_IO_RW_DIRECT))
+ cmdr |= SDMMC_CMD_PRV_DAT_WAIT;
+
if (cmd->flags & MMC_RSP_PRESENT) {
/* We expect a response, so set this bit */
cmdr |= SDMMC_CMD_RESP_EXP;
@@ -1263,7 +1267,8 @@
/* enable clock; only low power if no SDIO */
clk_en_a = SDMMC_CLKEN_ENABLE << slot->id;
- if (!test_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags))
+ if (!test_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags) &&
+ !(slot->mmc->caps2 & MMC_CAP2_WIFI_RK912))
clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id;
mci_writel(host, CLKENA, clk_en_a);
diff -ur linux-6.12.29/include/linux/mmc/host.h linux_for_rk915/include/linux/mmc/host.h
--- linux-6.12.29/include/linux/mmc/host.h 2025-05-18 06:25:00.000000000 +0000
+++ linux_for_rk915/include/linux/mmc/host.h 2025-06-28 17:45:54.422123779 +0000
@@ -404,6 +404,7 @@
#define MMC_CAP2_CRYPTO 0
#endif
#define MMC_CAP2_ALT_GPT_TEGRA (1 << 28) /* Host with eMMC that has GPT entry at a non-standard location */
+#define MMC_CAP2_WIFI_RK912 (1 << 29)
int fixed_drv_type; /* fixed driver type for non-removable media */
@@ -0,0 +1,12 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2024-present ArchR (https://github.com/archr-linux/Arch-R)
# Minimal per-device config: wire up the temperature sensors so System
# Information (archr-info) and EmulationStation show CPU/GPU temps. The
# quirks loader matches the folder name against /proc/device-tree/model
# exactly, so this folder name MUST equal the DTS `model` string.
cat <<CONF >/storage/.config/profile.d/001-device_config
DEVICE_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone0/temp"
DEVICE_GPU_TEMP_SENSOR="/sys/devices/virtual/thermal/thermal_zone1/temp"
CONF
@@ -0,0 +1,31 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2024-present ROCKNIX (https://github.com/ROCKNIX)
PKG_NAME="rk915"
PKG_VERSION="e2fd61651c272aab7bd7e76ba05e5682d7c1d211"
PKG_LICENSE="GPL"
PKG_SITE="https://github.com/AveyondFly/rk915"
PKG_URL="${PKG_SITE}/archive/${PKG_VERSION}.tar.gz"
PKG_LONGDESC="RK915 WiFi/BT SDIO driver"
PKG_TOOLCHAIN="manual"
PKG_IS_KERNEL_PKG="yes"
pre_make_target() {
unset LDFLAGS
}
make_target() {
kernel_make -C $(kernel_path) M=${PKG_BUILD} \
BUSIF=SDIO \
ROM=true \
CHIP=RK915
}
makeinstall_target() {
mkdir -p ${INSTALL}/$(get_full_module_dir)/${PKG_NAME}
cp ${PKG_BUILD}/*.ko ${INSTALL}/$(get_full_module_dir)/${PKG_NAME}
# Install firmware to kernel overlay
mkdir -p ${INSTALL}/$(get_full_firmware_dir)
cp ${PKG_BUILD}/firmware/*.bin ${INSTALL}/$(get_full_firmware_dir)/
}