94 lines
2.3 KiB
Bash
94 lines
2.3 KiB
Bash
#!/bin/sh
|
|
#===============================================================================
|
|
#
|
|
# Copyright (C) 2023 by Digi International Inc.
|
|
# All rights reserved.
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License version 2 as published by
|
|
# the Free Software Foundation.
|
|
#
|
|
#
|
|
# !Description: Initialize bluetooth hardware
|
|
#
|
|
#===============================================================================
|
|
|
|
HCI_IFACE="hci0"
|
|
MODULE_NAME="btnxpuart"
|
|
|
|
log() {
|
|
printf "<3>iw61x-bluetooth: %s\n" "${1}" >/dev/kmsg
|
|
}
|
|
|
|
# The power of the IW61x chip is managed by the WiFi DT entry.
|
|
# If WiFi is disabled, is needed to manage the power manually.
|
|
is_not_wifi() {
|
|
! [ -e "/proc/device-tree/wireless/mac-address" ]
|
|
}
|
|
|
|
power() {
|
|
is_not_wifi && gpioset 1 7="${1}"
|
|
}
|
|
|
|
set_btaddr() {
|
|
hciconfig ${HCI_IFACE} up
|
|
sleep 0.2
|
|
bt_addr=$(echo "$(fw_printenv -n btaddr)" | awk -F ":" '{ for(i=NF;i>=1;i--) printf "0x%s ", $i }')
|
|
hcitool -i ${HCI_IFACE} cmd 0x3f 0x0022 0xfe 0x06 ${bt_addr}
|
|
hciconfig ${HCI_IFACE} down
|
|
sleep 0.2
|
|
hciconfig ${HCI_IFACE} up
|
|
}
|
|
|
|
set_power_config() {
|
|
sh -e /lib/firmware/nxp/bt_power_config_US_CA_JP.sh
|
|
}
|
|
|
|
is_kernel_module_loaded() {
|
|
lsmod | grep -qs -w "^${MODULE_NAME}"
|
|
}
|
|
|
|
bluetooth_start() {
|
|
if ! [ -e "/proc/device-tree/bluetooth/mac-address" ]; then
|
|
log "[ERROR] Bluetooth mac-address not found"
|
|
return
|
|
fi
|
|
|
|
# If module is already loaded, skip
|
|
is_kernel_module_loaded && log "[ERROR] kernel module already present, skipping" && return 1
|
|
|
|
power 0 && sleep 0.2 && power 1
|
|
# Load manually the kernel module
|
|
modprobe "${MODULE_NAME}"
|
|
# Reconfigure the HCI interface with the expected MAC address and power levels
|
|
is_kernel_module_loaded && set_btaddr && set_power_config && log "Bluetooth activated" && return 0
|
|
log "[ERROR] Cannot initialize Bluetooth correctly" && return 1
|
|
}
|
|
|
|
bluetooth_stop() {
|
|
#
|
|
# The btnxpuart driver hits a null pointer dereference on module
|
|
# unloading when the interface is down. So as a workaround, make
|
|
# sure the interface is UP before unloading the module.
|
|
#
|
|
hciconfig "${HCI_IFACE}" up && rmmod "${MODULE_NAME}"
|
|
power 0
|
|
}
|
|
|
|
case "$1" in
|
|
start)
|
|
bluetooth_start
|
|
;;
|
|
stop)
|
|
bluetooth_stop
|
|
;;
|
|
restart)
|
|
$0 stop
|
|
$0 start
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {start|stop|restart}"
|
|
exit 1
|
|
;;
|
|
esac
|