Skip to content

Commit ffe8daa

Browse files
nirav-agrawaldanieldegrasse
authored andcommitted
drivers: bluetooth: add BT-CAL data load for NXP IW612/IW416 SoC
- Add support for default Annex-55 Bluetooth calibration data load for both IW612 and IW416 SoC. - Add support for default Annex-100 Bluetooth calibration data load for both IW612 and IW416 SoC. Signed-off-by: Nirav Agrawal <[email protected]>
1 parent f1931bb commit ffe8daa

File tree

2 files changed

+217
-7
lines changed

2 files changed

+217
-7
lines changed

drivers/bluetooth/hci/Kconfig.nxp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ config HCI_NXP_ENABLE_AUTO_SLEEP
1313
message to the Controller as the Host will need to wake it up.
1414

1515
config HCI_NXP_SET_CAL_DATA
16-
bool "BLE Controller calibration data"
16+
bool "Bluetooth Controller calibration data"
1717
help
18-
If enabled, the Host will send calibration data to the BLE Controller during HCI init.
18+
If enabled, the Host will send calibration data to the Bluetooth Controller during HCI init.
1919

2020
config HCI_NXP_SET_CAL_DATA_ANNEX100
21-
bool "BLE Controller calibration data annex 100"
21+
bool "Bluetooth Controller calibration data annex 100"
2222
help
23-
If enabled, the Host will send calibration data annex 100 to the BLE Controller during HCI
23+
If enabled, the Host will send calibration data annex 100 to the Bluetooth Controller during HCI
2424
init.
2525

2626
config HCI_NXP_RX_THREAD

drivers/bluetooth/hci/hci_nxp_setup.c

Lines changed: 213 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,25 @@ LOG_MODULE_REGISTER(bt_nxp_ctlr);
2929

3030
#define DT_DRV_COMPAT nxp_bt_hci_uart
3131

32-
#define FW_UPLOAD_CHANGE_TIMEOUT_RETRY_COUNT 6
32+
#define FW_UPLOAD_CHANGE_TIMEOUT_RETRY_COUNT 6
33+
#define HCI_CMD_STORE_BT_CAL_DATA_ANNEX100_OCF 0xFF
34+
#define HCI_CMD_STORE_BT_CAL_DATA_PARAM_ANNEX100_LENGTH 16
35+
#define HCI_CMD_STORE_BT_CAL_DATA_OCF 0x61
36+
#define HCI_CMD_STORE_BT_CAL_DATA_PARAM_LENGTH 32
3337

3438
extern const unsigned char *bt_fw_bin;
3539
extern const unsigned int bt_fw_bin_len;
3640

3741
static const struct device *uart_dev = DEVICE_DT_GET(DT_INST_GPARENT(0));
3842

43+
#if !defined(CONFIG_HCI_NXP_SET_CAL_DATA)
44+
#define bt_nxp_set_calibration_data_annex55() 0
45+
#endif
46+
47+
#if !defined(CONFIG_HCI_NXP_SET_CAL_DATA_ANNEX100)
48+
#define bt_nxp_set_calibration_data_annex100() 0
49+
#endif
50+
3951
#if DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios)
4052
struct gpio_dt_spec sdio_reset = GPIO_DT_SPEC_GET(DT_DRV_INST(0), sdio_reset_gpios);
4153
#endif /* DT_NODE_HAS_PROP(DT_DRV_INST(0), sdio_reset_gpios) */
@@ -1171,6 +1183,189 @@ static int bt_nxp_ctlr_init(void)
11711183
return 0;
11721184
}
11731185

1186+
#if defined(CONFIG_HCI_NXP_SET_CAL_DATA)
1187+
1188+
static int bt_nxp_set_calibration_data_annex55(void)
1189+
{
1190+
int ret = 0;
1191+
uint16_t opcode = BT_OP(BT_OGF_VS, HCI_CMD_STORE_BT_CAL_DATA_OCF);
1192+
1193+
const uint8_t hci_cal_data_annex55[HCI_CMD_STORE_BT_CAL_DATA_PARAM_LENGTH] = {
1194+
#if defined(CONFIG_BT_NXP_NW612)
1195+
0x00, /* Sequence Number : 0x00 */
1196+
0x01, /* Action : 0x01 */
1197+
0x01, /* Type : Not use CheckSum */
1198+
0x1C, /* File Length : 0x1C */
1199+
0x37, /* BT Annex Type : BT CFG */
1200+
0x33, /* Checksum : 0x71 */
1201+
0x1C, /* Annex Length LSB: 0x001C */
1202+
0x00, /* Annex Length MSB: 0x001C */
1203+
0x00, /* Pointer For Next Annex[0] : 0x00000000 */
1204+
0x00, /* Pointer For Next Annex[1] : 0x00000000 */
1205+
0x00, /* Pointer For Next Annex[2] : 0x00000000 */
1206+
0x00, /* Pointer For Next Annex[3] : 0x00000000 */
1207+
0x01, /* Annex Version : 0x01 */
1208+
0x81, /* External Xtal Calibration Value : 0x7d */
1209+
0x0D, /* Initial TX Power : 13 */
1210+
0x07, /* Front End Loss : 0x07 */
1211+
0x28, /* BT Options : */
1212+
/* BIT[0] Force Class 2 operation = 0 */
1213+
/* BIT[1] Disable Pwr-ctrl for class 2=0 */
1214+
/* BIT[2] MiscFlg(to indicate ext.XTAL)=0 */
1215+
/* BIT[3] Used Internal Sleep Clock = 1 */
1216+
/* BIT[4] BT AOA location support = 0 */
1217+
/* BIT[5] Force Class 1 mode = 1 */
1218+
/* BIT[7:6] Reserved */
1219+
0x00, /* AOANumberOfAntennas: 0x00 */
1220+
0x00, /* RSSI Golden Low : 0 */
1221+
0x00, /* RSSI Golden High : 0 */
1222+
0xC0, /* UART Baud Rate[0] : 0x002DC6C0(3000000) */
1223+
0xC6, /* UART Baud Rate[1] : 0x002DC6C0(3000000) */
1224+
0x2D, /* UART Baud Rate[2] : 0x002DC6C0(3000000) */
1225+
0x00, /* UART Baud Rate[3] : 0x002DC6C0(3000000) */
1226+
0x00, /* BdAddress[0] : 0x000000000000 */
1227+
0x00, /* BdAddress[1] : 0x000000000000 */
1228+
0x00, /* BdAddress[2] : 0x000000000000 */
1229+
0x00, /* BdAddress[3] : 0x000000000000 */
1230+
0x00, /* BdAddress[4] : 0x000000000000 */
1231+
0x00, /* BdAddress[5] : 0x000000000000 */
1232+
0xF0, /* Encr_Key_Len[3:0]: MinEncrKeyLen = 0x0 */
1233+
/* ExEncrKeyLen = 0xF */
1234+
0x00, /* RegionCode : 0x00 */
1235+
#elif defined(CONFIG_BT_NXP_IW416)
1236+
0x00, /* Sequence Number : 0x00 */
1237+
0x01, /* Action : 0x01 */
1238+
0x01, /* Type : Not use CheckSum */
1239+
0x1C, /* File Length : 0x1C */
1240+
0x37, /* BT Annex Type : BT CFG */
1241+
0x33, /* Checksum : 0x71 */
1242+
0x1C, /* Annex Length LSB: 0x001C */
1243+
0x00, /* Annex Length MSB: 0x001C */
1244+
0x00, /* Pointer For Next Annex[0] : 0x00000000 */
1245+
0x00, /* Pointer For Next Annex[1] : 0x00000000 */
1246+
0x00, /* Pointer For Next Annex[2] : 0x00000000 */
1247+
0x00, /* Pointer For Next Annex[3] : 0x00000000 */
1248+
0x01, /* Annex Version : 0x01 */
1249+
0x00, /* External Xtal Calibration Value */
1250+
0x03, /* Initial TX Power : 0x03 */
1251+
0x03, /* Front End Loss : 0x03 */
1252+
0x00, /* BT Options : */
1253+
/* BIT[0] Force Class 2 operation = 0 */
1254+
/* BIT[1] Disable Pwr Ctrl for class 2=0 */
1255+
/* BIT[2] MiscFlg(to indicate ext.XTAL)=0 */
1256+
/* BIT[3] Used Internal Sleep Clock = 0 */
1257+
/* BIT[4] BT AOA localtion support = 0 */
1258+
/* BIT[5] Force Class 1 mode = 0 */
1259+
/* BIT[7:6] Reserved */
1260+
0x00, /* AOANumberOfAntennas: 0x00 */
1261+
0xBA, /* RSSI Golden Low : 0 */
1262+
0xCE, /* RSSI Golden High : 0 */
1263+
0xC0, /* UART Baud Rate[0] : 0x002DC6C0(3000000) */
1264+
0xC6, /* UART Baud Rate[1] : 0x002DC6C0(3000000) */
1265+
0x2D, /* UART Baud Rate[2] : 0x002DC6C0(3000000) */
1266+
0x00, /* UART Baud Rate[3] : 0x002DC6C0(3000000) */
1267+
0x00, /* BdAddress[0] : 0x000000000000 */
1268+
0x00, /* BdAddress[1] : 0x000000000000 */
1269+
0x00, /* BdAddress[2] : 0x000000000000 */
1270+
0x00, /* BdAddress[3] : 0x000000000000 */
1271+
0x00, /* BdAddress[4] : 0x000000000000 */
1272+
0x00, /* BdAddress[5] : 0x000000000000 */
1273+
0xF0, /* Encr_Key_Len[3:0]: MinEncrKeyLen = 0x0 */
1274+
/* ExEncrKeyLen = 0xF */
1275+
0x00, /* RegionCode : 0x00 */
1276+
#else
1277+
#error "BT Calibration data (annex-55) is not given for selected chipset"
1278+
#endif
1279+
};
1280+
1281+
if (IS_ENABLED(CONFIG_BT_HCI_HOST)) {
1282+
struct net_buf *buf;
1283+
1284+
buf = bt_hci_cmd_create(opcode, HCI_CMD_STORE_BT_CAL_DATA_PARAM_LENGTH);
1285+
if (buf == NULL) {
1286+
LOG_ERR("Unable to allocate command buffer");
1287+
return -ENOMEM;
1288+
}
1289+
1290+
net_buf_add_mem(buf, hci_cal_data_annex55, HCI_CMD_STORE_BT_CAL_DATA_PARAM_LENGTH);
1291+
1292+
ret = bt_hci_cmd_send_sync(opcode, buf, NULL);
1293+
if (ret) {
1294+
LOG_ERR("Failed to send set-calibration cmd (err %d)", ret);
1295+
return ret;
1296+
}
1297+
1298+
(void)k_msleep(CONFIG_BT_H4_NXP_CTLR_WAIT_TIME_AFTER_BAUDRATE_UPDATE);
1299+
}
1300+
1301+
return ret;
1302+
}
1303+
#endif /*CONFIG_HCI_NXP_SET_CAL_DATA*/
1304+
1305+
#if defined(CONFIG_HCI_NXP_SET_CAL_DATA_ANNEX100)
1306+
1307+
static int bt_nxp_set_calibration_data_annex100(void)
1308+
{
1309+
int ret = 0;
1310+
const uint8_t hci_cal_data_annex100[HCI_CMD_STORE_BT_CAL_DATA_PARAM_ANNEX100_LENGTH] = {
1311+
#if defined(CONFIG_BT_NXP_NW612)
1312+
0x64, /* Annex Type : 0x64 */
1313+
0x83, /* Checksum */
1314+
0x10, 0x00, /* Length */
1315+
0x00, 0x00, 0x00, 0x00, /* Pointer for next Annex-Structure */
1316+
0x01, /* Ext PA Present (1 bit) + */
1317+
/* Ext. PA Gain (7 bits) */
1318+
0x00, /* Ext Antenna Gain(1 bit) + */
1319+
/* Ext. Antenna Gain Val(4 bits) */
1320+
0x04, 0x00, /* BT / LE Ext PA FEM CTRL Bitmask */
1321+
0x01, /* Ext LNA Present (1 bit) + */
1322+
/* Ext LNA Gain (7 bits) */
1323+
0x00, /* Reserved */
1324+
0x04, 0x00 /* BT / LE Ext LNA FEM CTRL Bitmask */
1325+
#elif defined(CONFIG_BT_NXP_IW416)
1326+
0x64, /* Annex Type : 0x64 */
1327+
0x83, /* Checksum */
1328+
0x10, 0x00, /* Length */
1329+
0x00, 0x00, 0x00, 0x00, /* Pointer for next Annex-Structure */
1330+
0x01, /* Ext PA Present (1 bit) + */
1331+
/* Ext. PA Gain (7 bits) */
1332+
0x00, /* Ext Antenna Gain(1 bit) + */
1333+
/* Ext. Antenna Gain Val (4 bits) */
1334+
0x0C, 0x00, /* BT / LE Ext PA FEM CTRL Bitmask */
1335+
0x01, /* Ext LNA Present (1 bit) + */
1336+
/* Ext LNA Gain (7 bits) */
1337+
0x00, /* Reserved */
1338+
0x0C, 0x00 /* BT/LE Ext LNA FEM CTRL Bitmask */
1339+
#else
1340+
#error "BT Calibration data (annex-100) is not given for selected chipset"
1341+
#endif
1342+
};
1343+
1344+
uint16_t opcode = BT_OP(BT_OGF_VS, HCI_CMD_STORE_BT_CAL_DATA_ANNEX100_OCF);
1345+
1346+
if (IS_ENABLED(CONFIG_BT_HCI_HOST)) {
1347+
struct net_buf *buf;
1348+
1349+
buf = bt_hci_cmd_create(opcode, HCI_CMD_STORE_BT_CAL_DATA_PARAM_ANNEX100_LENGTH);
1350+
if (buf == NULL) {
1351+
LOG_ERR("Unable to allocate command buffer");
1352+
return -ENOMEM;
1353+
}
1354+
1355+
net_buf_add_mem(buf, hci_cal_data_annex100,
1356+
HCI_CMD_STORE_BT_CAL_DATA_PARAM_ANNEX100_LENGTH);
1357+
1358+
ret = bt_hci_cmd_send_sync(opcode, buf, NULL);
1359+
if (ret) {
1360+
LOG_ERR("Failed to send set-calibration cmd (err %d)", ret);
1361+
return ret;
1362+
}
1363+
}
1364+
1365+
return ret;
1366+
}
1367+
#endif /* defined(CONFIG_HCI_NXP_SET_CAL_DATA_ANNEX100) */
1368+
11741369
int bt_hci_transport_setup(const struct device *dev)
11751370
{
11761371
int ret = 0;
@@ -1231,6 +1426,7 @@ int bt_h4_vnd_setup(const struct device *dev)
12311426
flowcontrol_of_hci = (bool)DT_PROP_OR(DT_DRV_INST(0), hw_flow_control, false);
12321427

12331428
if (operation_speed == default_speed) {
1429+
fw_upload.is_setup_done = true;
12341430
return 0;
12351431
}
12361432

@@ -1240,7 +1436,7 @@ int bt_h4_vnd_setup(const struct device *dev)
12401436
return err;
12411437
}
12421438

1243-
/* BT waiting time after controller bandrate updated */
1439+
/* BT waiting time after controller bandrate updated */
12441440
(void)k_msleep(CONFIG_BT_H4_NXP_CTLR_WAIT_TIME_AFTER_BAUDRATE_UPDATE);
12451441
}
12461442

@@ -1250,7 +1446,21 @@ int bt_h4_vnd_setup(const struct device *dev)
12501446
return err;
12511447
}
12521448

1253-
fw_upload.is_setup_done = true;
1449+
if (!fw_upload.is_setup_done) {
1450+
err = bt_nxp_set_calibration_data_annex55();
1451+
if (err) {
1452+
LOG_ERR("Fail to load annex-55 calibration data");
1453+
return err;
1454+
}
1455+
1456+
err = bt_nxp_set_calibration_data_annex100();
1457+
if (err) {
1458+
LOG_ERR("Fail to load annex-100 calibration data");
1459+
return err;
1460+
}
1461+
1462+
fw_upload.is_setup_done = true;
1463+
}
12541464

12551465
return 0;
12561466
}

0 commit comments

Comments
 (0)