Tactility/Devices/m5stack-tab5/m5stack,tab5.dts
Ken Van Hoeylandt cb4ce5246d
USB host refactored (#684)
- Create `USB_HOST_TYPE` base driver in TactilityKernel
- Refactor esp32_usbhost dts format, and create child devices dynamically
- Use PSRAM for task stacks where possible: saving 20 kB from just the task stacks, but roughly 30 kB when nothing is connected.
- Allow the user to disable USB host interface in the USB settings app, saving an additionaly 20 kB of IRAM when nothing was connected.
- Change listener-based APIs to subscribe and poll/await pattern. This avoids callstacks of apps and services leaking into the USB API

This results in big IRAM savings: 30 kB when USB host is on and nothing is connected, and 50 kB total when USB host is disabled.
This brings the total free IRAM after boot from roughly 170 kB to 200 kB (host enabled) or 220 kB (host disabled).
2026-10-10 13:33:32 +02:00

223 lines
5.4 KiB
Plaintext

/dts-v1/;
#include <tactility/bindings/root.h>
#include <tactility/bindings/esp32_ble.h>
#include <tactility/bindings/esp32_gpio.h>
#include <tactility/bindings/esp32_grove.h>
#include <tactility/bindings/esp32_i2c_master.h>
#include <tactility/bindings/esp32_i2s.h>
#include <tactility/bindings/esp32_pwm_ledc.h>
#include <tactility/bindings/esp32_sdmmc.h>
#include <tactility/bindings/esp32_uart.h>
#include <tactility/bindings/esp32_usbdevice.h>
#include <tactility/bindings/esp32_usbhost.h>
#include <tactility/bindings/esp32_wifi.h>
#include <tactility/bindings/gpio_hog.h>
#include <tactility/bindings/pwm_backlight.h>
#include <bindings/bmi270.h>
#include <bindings/es7210.h>
#include <bindings/es8388.h>
#include <bindings/ina226.h>
#include <bindings/pi4ioe5v6408.h>
#include <bindings/rx8130ce.h>
#include <bindings/sc2356.h>
/ {
compatible = "root";
model = "Tab5";
wifi0 {
compatible = "espressif,esp32-wifi";
status = "disabled";
};
ble0 {
compatible = "espressif,esp32-ble";
};
gpio0 {
compatible = "espressif,esp32-gpio";
gpio-count = <55>;
};
display_backlight_pwm {
compatible = "espressif,esp32-pwm-ledc";
pin = <&gpio0 22 GPIO_FLAG_NONE>;
period-ns = <200000>; // 5000 Hz
ledc-timer = <1>;
ledc-channel = <0>;
};
display_backlight {
compatible = "pwm-backlight";
pwm = <&display_backlight_pwm>;
};
// Declared before i2c0 so it starts before the es8388/es7210 codecs that reference it
i2s0 {
compatible = "espressif,esp32-i2s";
port = <I2S_NUM_0>;
pin-bclk = <&gpio0 27 GPIO_FLAG_NONE>;
pin-ws = <&gpio0 29 GPIO_FLAG_NONE>;
pin-data-out = <&gpio0 26 GPIO_FLAG_NONE>;
pin-data-in = <&gpio0 28 GPIO_FLAG_NONE>;
pin-mclk = <&gpio0 30 GPIO_FLAG_NONE>;
};
i2c_internal: i2c0 {
compatible = "espressif,esp32-i2c-master";
port = <I2C_NUM_0>;
clock-frequency = <400000>;
pin-sda = <&gpio0 31 GPIO_FLAG_PULL_UP>;
pin-scl = <&gpio0 32 GPIO_FLAG_PULL_UP>;
io_expander0 {
compatible = "diodes,pi4ioe5v6408";
reg = <0x43>;
};
io_expander1 {
compatible = "diodes,pi4ioe5v6408";
reg = <0x44>;
};
bmi270 {
compatible = "bosch,bmi270";
reg = <0x68>;
};
es8388 {
compatible = "everest,es8388";
reg = <0x10>;
i2s = <&i2s0>;
};
es7210 {
compatible = "everest,es7210";
reg = <0x40>;
i2s = <&i2s0>;
// Per schematic: MIC1/MIC2 are the two onboard capsules (U17/U16).
// MIC3 is not a microphone -- MIC3P is tapped from HPOUT_L (AEC_P) as an
// acoustic-echo-cancellation reference, MIC3N goes to AGND. MIC4 is the
// external headset-mic jack input (HPMIC), also not onboard. Select only
// the two real capsules; MIC3/MIC4 would otherwise show up as silent (or
// speaker-echoing) extra channels.
mic-mask = <3>;
};
rx8130ce {
compatible = "epson,rx8130ce";
reg = <0x32>;
};
ina226 {
compatible = "ti,ina226";
reg = <0x41>;
shunt-milliohms = <5>;
// 2S NP-F550 pack
power-supply;
power-supply-reference-voltage-mv = <8400>;
power-supply-min-voltage-mv = <6400>;
};
sc2356 {
compatible = "smartsens,sc2356";
rotation-offset = <270>;
reg = <0x36>;
// Pulsed by the sc2356 driver itself in start_device, not a gpio-hog: the driver's
// I2C probe otherwise races a bare hog's pin release with no settle delay (the hog
// also only starts after this node, since it's a root-level sibling declared later
// in this file - always too late).
pin-reset = <&io_expander0 6 GPIO_FLAG_ACTIVE_LOW>;
};
};
exp0_rf_internal_external {
compatible = "gpio-hog";
pin = <&io_expander0 0 GPIO_FLAG_NONE>;
mode = <GPIO_HOG_MODE_OUTPUT_LOW>;
};
exp0_external_5v_bus_enable {
compatible = "gpio-hog";
pin = <&io_expander0 2 GPIO_FLAG_NONE>;
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
};
exp1_c6_wlan_enable {
compatible = "gpio-hog";
pin = <&io_expander1 0 GPIO_FLAG_NONE>;
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
};
exp1_usb_a_5v_enable {
compatible = "gpio-hog";
pin = <&io_expander1 3 GPIO_FLAG_NONE>;
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
};
exp1_ip2326_chg_stat_led {
compatible = "gpio-hog";
pin = <&io_expander1 6 GPIO_FLAG_NONE>;
mode = <GPIO_HOG_MODE_OUTPUT_LOW>;
};
port_a: grove0 {
compatible = "espressif,esp32-grove";
defaultMode = <GROVE_MODE_I2C>;
pinSdaTx = <&gpio0 53 GPIO_FLAG_NONE>;
pinSclRx = <&gpio0 54 GPIO_FLAG_NONE>;
uartPort = <UART_NUM_1>;
i2cPort = <I2C_NUM_1>;
i2cClockFrequency = <100000>;
};
i2c_keyboard: i2c2 {
compatible = "espressif,esp32-i2c-master";
port = <LP_I2C_NUM_0>;
clock-frequency = <400000>;
clock-source = <LP_I2C_SCLK_DEFAULT>;
pin-sda = <&gpio0 0 GPIO_FLAG_PULL_UP>;
pin-scl = <&gpio0 1 GPIO_FLAG_PULL_UP>;
};
sdmmc0 {
compatible = "espressif,esp32-sdmmc";
pin-clk = <&gpio0 43 GPIO_FLAG_NONE>;
pin-cmd = <&gpio0 44 GPIO_FLAG_NONE>;
pin-d0 = <&gpio0 39 GPIO_FLAG_NONE>;
pin-d1 = <&gpio0 40 GPIO_FLAG_NONE>;
pin-d2 = <&gpio0 41 GPIO_FLAG_NONE>;
pin-d3 = <&gpio0 42 GPIO_FLAG_NONE>;
bus-width = <4>;
slot = <SDMMC_HOST_SLOT_0>;
max-freq-khz = <SDMMC_FREQ_HIGHSPEED>;
on-chip-ldo-chan = <4>;
};
usbhost0 {
compatible = "espressif,esp32-usbhost";
peripheral-map = <0>;
};
usbdevice0 {
compatible = "espressif,esp32-usbdevice";
usbdevicehid0 {
compatible = "espressif,esp32-usbdevice-hid";
};
usbdevicemsc0 {
compatible = "espressif,esp32-usbdevice-msc";
};
usbdevicemidi0 {
compatible = "espressif,esp32-usbdevice-midi";
};
usbdevicecdc0 {
compatible = "espressif,esp32-usbdevice-cdc";
};
};
};