sunxi: board: add a config option to fixup a Bluetooth address

Some Bluetooth controllers, like the BCM4345C5 of the Orange Pi 3,
ship with the controller default address.

Add a config option to fix it up so it can function properly.

Signed-off-by: Andre Heider <a.heider@gmail.com>
Tested-by: Ondrej Jirman <megous@megous.com>
Acked-by: Maxime Ripard <mripard@kernel.org>
[rebased]
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
Andre Heider 2021-10-01 19:29:00 +01:00 committed by Andre Przywara
parent 928f4f4868
commit 9267ff89ee
2 changed files with 46 additions and 0 deletions

View File

@ -1016,4 +1016,15 @@ config PINEPHONE_DT_SELECTION
Enable this option to automatically select the device tree for the Enable this option to automatically select the device tree for the
correct PinePhone hardware revision during boot. correct PinePhone hardware revision during boot.
config BLUETOOTH_DT_DEVICE_FIXUP
string "Fixup the Bluetooth controller address"
default ""
help
This option specifies the DT compatible name of the Bluetooth
controller for which to set the "local-bd-address" property.
Set this option if your device ships with the Bluetooth controller
default address.
The used address is "bdaddr" if set, and "ethaddr" with the LSB
flipped elsewise.
endif endif

View File

@ -39,6 +39,7 @@
#include <u-boot/crc.h> #include <u-boot/crc.h>
#include <env_internal.h> #include <env_internal.h>
#include <linux/libfdt.h> #include <linux/libfdt.h>
#include <fdt_support.h>
#include <nand.h> #include <nand.h>
#include <net.h> #include <net.h>
#include <spl.h> #include <spl.h>
@ -913,6 +914,38 @@ int board_late_init(void)
return 0; return 0;
} }
static void bluetooth_dt_fixup(void *blob)
{
/* Some devices ship with a Bluetooth controller default address.
* Set a valid address through the device tree.
*/
uchar tmp[ETH_ALEN], bdaddr[ETH_ALEN];
unsigned int sid[4];
int i;
if (!CONFIG_BLUETOOTH_DT_DEVICE_FIXUP[0])
return;
if (eth_env_get_enetaddr("bdaddr", tmp)) {
/* Convert between the binary formats of the corresponding stacks */
for (i = 0; i < ETH_ALEN; ++i)
bdaddr[i] = tmp[ETH_ALEN - i - 1];
} else {
if (!get_unique_sid(sid))
return;
bdaddr[0] = ((sid[3] >> 0) & 0xff) ^ 1;
bdaddr[1] = (sid[3] >> 8) & 0xff;
bdaddr[2] = (sid[3] >> 16) & 0xff;
bdaddr[3] = (sid[3] >> 24) & 0xff;
bdaddr[4] = (sid[0] >> 0) & 0xff;
bdaddr[5] = 0x02;
}
do_fixup_by_compat(blob, CONFIG_BLUETOOTH_DT_DEVICE_FIXUP,
"local-bd-address", bdaddr, ETH_ALEN, 1);
}
int ft_board_setup(void *blob, struct bd_info *bd) int ft_board_setup(void *blob, struct bd_info *bd)
{ {
int __maybe_unused r; int __maybe_unused r;
@ -923,6 +956,8 @@ int ft_board_setup(void *blob, struct bd_info *bd)
*/ */
setup_environment(blob); setup_environment(blob);
bluetooth_dt_fixup(blob);
#ifdef CONFIG_VIDEO_DT_SIMPLEFB #ifdef CONFIG_VIDEO_DT_SIMPLEFB
r = sunxi_simplefb_setup(blob); r = sunxi_simplefb_setup(blob);
if (r) if (r)