####################################################################
# Script : /etc/rc.d/rc.platform/aarch64/sc8280xp
# Purpose: Perform boot time configuration activities for Hardware
#          Models using the sc8280xp SoC.  This includes:
#          * Lenovo ThinkPad X13s (Snapdragon)
# Caller : This script is executed from /etc/rc.d/rc.platform
#          (which is loaded from /etc/rc.d/rc.M prior to rc.local) 
# Author : Brenton Earl <el0226@slackware.com>
#	   Based on rk3399 "platform script" by Stuart Winter 
# Date...: 25-May-2024
####################################################################
# Note: This configuration file is managed by the Slackware packages
#       and is NOT user serviceable.  Any changes made here will be
#       removed when the 'a/sysvinit-scripts' package is upgraded.
#
#       To adjust the settings used for the actions applied here,
#       edit /etc/rc.d/rc.platform.conf and the settings will become
#       operative at the next boot.
####################################################################

# Lenovo ThinkPad X13s:
case "$HWM" in
	"Lenovo ThinkPad X13s"*)
	echo "Running Lenovo ThinkPad X13s Tweaks..."
       # USB: dwc3 a800000.usb (second USB-C port) and a400000.usb (multiport,
       # internal devices) can fail their first probe with -ETIMEDOUT
       # ("DWC3 controller soft reset failed" / a PHY timeout). a800000 cannot be
       # bound from the OS InitRD, only once the OS proper is up; a400000 is
       # normally bound by the OS InitRD (snapdragon hwm_hook_post-modload) and is
       # included here as a fallback. Retry in the background for up to about
       # 60 seconds so that boot is not delayed.
       ( for i in $(seq 1 30) ; do
            left=""
            for d in a800000.usb a400000.usb ; do
               [ -e /sys/bus/platform/devices/$d ] || continue
               [ -e /sys/bus/platform/drivers/dwc3/$d ] && continue
               echo $d 2>/dev/null > /sys/bus/platform/drivers/dwc3/bind || left="$left $d"
               done
               [ -z "$left" ] && exit 0
               sleep 2
         done
         logger -t rc.platform "sc8280xp: USB controller(s) still unbound:$left" ) &

       # Bluetooth: the WCN6855 starts with a placeholder address from its
       # firmware, so the driver takes the address from the Device Tree
       # ('local-bd-address'), which the X13s firmware does not fill in. hci0 is
       # then registered as unconfigured and bluetoothd never sees it until a
       # public address is set. Use X13S_BT_ADDR if it is set (for example in
       # /etc/rc.d/rc.platform.conf); otherwise create a random, locally
       # administered address once and keep it in /var/lib/bluetooth, so paired
       # devices still recognise this machine after a reboot. hci0 appears only
       # once hci_uart has loaded, so wait for it in the background.
       ( command -v btmgmt > /dev/null || exit 0
         btaddr_file=/var/lib/bluetooth/x13s-public-addr
         btaddr="$X13S_BT_ADDR"
         if [ -z "$btaddr" ]; then
            if [ -s "$btaddr_file" ]; then
                  btaddr=$(cat "$btaddr_file")
                else
                  btaddr=$(od -An -N5 -tu1 /dev/urandom | awk '{ printf "02:%02X:%02X:%02X:%02X:%02X", $1, $2, $3, $4, $5 }')
                  mkdir -pm 700 /var/lib/bluetooth
                  echo "$btaddr" > "$btaddr_file"
            fi
          fi
          for i in $(seq 1 60) ; do
             [ -e /sys/class/bluetooth/hci0 ] && break
             sleep 1
          done
          [ -e /sys/class/bluetooth/hci0 ] || exit 0
          # Only set the address while the controller is still missing one:
          btmgmt --index 0 config 2>/dev/null | grep -q 'missing options:.*public-address' || exit 0
          if btmgmt --index 0 public-addr "$btaddr" > /dev/null 2>&1 ; then
             logger -t rc.platform "sc8280xp: Bluetooth public address set to $btaddr"
           else
             logger -t rc.platform "sc8280xp: could not set the Bluetooth public address $btaddr"
          fi ) &
      ;;
esac
