Skip to content

Commit c585a92

Browse files
ssreemanVudentz
authored andcommitted
Bluetooth: btintel: Set Per Platform Antenna Gain(PPAG)
Antenna gain is defined as the antenna’s ability to increase the Tx power in a given direction. Intel is certifying its products with fixed reference antenna peak gain values (3/5dBi). The feature takes into account the actual antenna gain, and increases output power values, which results in a performance improvement. After firmware download is completed, driver reads from ACPI table and configures PPAG as required. ACPI table entry for PPAG is defined as below. Name (PPAG, Package (0x02) { 0x00000001, Package (0x02) { 0x00000012, /* Bluetooth Domain */ 0x00000001 /* 1 - Enable PPAG, 0 - Disable PPAG */ } }) btmon log: < HCI Command: Intel Configure Per Platform Antenna Gain (0x3f|0x0219) plen 12 Mcc: 0x00000000 Selector: Enable Delta: 0x00000000 > HCI Event: Command Complete (0x0e) plen 4 Intel Configure Per Platform Antenna Gain (0x3f|0x0219) ncmd 1 Status: Success (0x00) Signed-off-by: Kiran K <[email protected]> Signed-off-by: Seema Sreemantha <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent 5cd3970 commit c585a92

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

drivers/bluetooth/btintel.c

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/module.h>
1010
#include <linux/firmware.h>
1111
#include <linux/regmap.h>
12+
#include <linux/acpi.h>
1213
#include <asm/unaligned.h>
1314

1415
#include <net/bluetooth/bluetooth.h>
@@ -24,6 +25,9 @@
2425
#define ECDSA_OFFSET 644
2526
#define ECDSA_HEADER_LEN 320
2627

28+
#define BTINTEL_PPAG_NAME "PPAG"
29+
#define BTINTEL_PPAG_PREFIX "\\_SB_.PCI0.XHCI.RHUB"
30+
2731
#define CMD_WRITE_BOOT_PARAMS 0xfc0e
2832
struct cmd_write_boot_params {
2933
__le32 boot_addr;
@@ -1278,6 +1282,63 @@ static int btintel_read_debug_features(struct hci_dev *hdev,
12781282
return 0;
12791283
}
12801284

1285+
static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data,
1286+
void **ret)
1287+
{
1288+
acpi_status status;
1289+
size_t len;
1290+
struct btintel_ppag *ppag = data;
1291+
union acpi_object *p, *elements;
1292+
struct acpi_buffer string = {ACPI_ALLOCATE_BUFFER, NULL};
1293+
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
1294+
struct hci_dev *hdev = ppag->hdev;
1295+
1296+
status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
1297+
if (ACPI_FAILURE(status)) {
1298+
bt_dev_warn(hdev, "ACPI Failure: %s", acpi_format_exception(status));
1299+
return status;
1300+
}
1301+
1302+
if (strncmp(BTINTEL_PPAG_PREFIX, string.pointer,
1303+
strlen(BTINTEL_PPAG_PREFIX))) {
1304+
kfree(string.pointer);
1305+
return AE_OK;
1306+
}
1307+
1308+
len = strlen(string.pointer);
1309+
if (strncmp((char *)string.pointer + len - 4, BTINTEL_PPAG_NAME, 4)) {
1310+
kfree(string.pointer);
1311+
return AE_OK;
1312+
}
1313+
kfree(string.pointer);
1314+
1315+
status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
1316+
if (ACPI_FAILURE(status)) {
1317+
bt_dev_warn(hdev, "ACPI Failure: %s", acpi_format_exception(status));
1318+
return status;
1319+
}
1320+
1321+
p = buffer.pointer;
1322+
ppag = (struct btintel_ppag *)data;
1323+
1324+
if (p->type != ACPI_TYPE_PACKAGE || p->package.count != 2) {
1325+
kfree(buffer.pointer);
1326+
bt_dev_warn(hdev, "Invalid object type: %d or package count: %d",
1327+
p->type, p->package.count);
1328+
return AE_ERROR;
1329+
}
1330+
1331+
elements = p->package.elements;
1332+
1333+
/* PPAG table is located at element[1] */
1334+
p = &elements[1];
1335+
1336+
ppag->domain = (u32)p->package.elements[0].integer.value;
1337+
ppag->mode = (u32)p->package.elements[1].integer.value;
1338+
kfree(buffer.pointer);
1339+
return AE_CTRL_TERMINATE;
1340+
}
1341+
12811342
static int btintel_set_debug_features(struct hci_dev *hdev,
12821343
const struct intel_debug_features *features)
12831344
{
@@ -2251,6 +2312,58 @@ static int btintel_configure_offload(struct hci_dev *hdev)
22512312
return err;
22522313
}
22532314

2315+
static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver)
2316+
{
2317+
acpi_status status;
2318+
struct btintel_ppag ppag;
2319+
struct sk_buff *skb;
2320+
struct btintel_loc_aware_reg ppag_cmd;
2321+
2322+
/* PPAG is not supported if CRF is HrP2, Jfp2, JfP1 */
2323+
switch (ver->cnvr_top & 0xFFF) {
2324+
case 0x504: /* Hrp2 */
2325+
case 0x202: /* Jfp2 */
2326+
case 0x201: /* Jfp1 */
2327+
return;
2328+
}
2329+
2330+
memset(&ppag, 0, sizeof(ppag));
2331+
2332+
ppag.hdev = hdev;
2333+
status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
2334+
ACPI_UINT32_MAX, NULL,
2335+
btintel_ppag_callback, &ppag, NULL);
2336+
2337+
if (ACPI_FAILURE(status)) {
2338+
/* Do not log warning message if ACPI entry is not found */
2339+
if (status == AE_NOT_FOUND)
2340+
return;
2341+
bt_dev_warn(hdev, "PPAG: ACPI Failure: %s", acpi_format_exception(status));
2342+
return;
2343+
}
2344+
2345+
if (ppag.domain != 0x12) {
2346+
bt_dev_warn(hdev, "PPAG-BT Domain disabled");
2347+
return;
2348+
}
2349+
2350+
/* PPAG mode, BIT0 = 0 Disabled, BIT0 = 1 Enabled */
2351+
if (!(ppag.mode & BIT(0))) {
2352+
bt_dev_dbg(hdev, "PPAG disabled");
2353+
return;
2354+
}
2355+
2356+
ppag_cmd.mcc = cpu_to_le32(0);
2357+
ppag_cmd.sel = cpu_to_le32(0); /* 0 - Enable , 1 - Disable, 2 - Testing mode */
2358+
ppag_cmd.delta = cpu_to_le32(0);
2359+
skb = __hci_cmd_sync(hdev, 0xfe19, sizeof(ppag_cmd), &ppag_cmd, HCI_CMD_TIMEOUT);
2360+
if (IS_ERR(skb)) {
2361+
bt_dev_warn(hdev, "Failed to send PPAG Enable (%ld)", PTR_ERR(skb));
2362+
return;
2363+
}
2364+
kfree_skb(skb);
2365+
}
2366+
22542367
static int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
22552368
struct intel_version_tlv *ver)
22562369
{
@@ -2297,6 +2410,9 @@ static int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
22972410

22982411
hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT);
22992412

2413+
/* Set PPAG feature */
2414+
btintel_set_ppag(hdev, ver);
2415+
23002416
/* Read the Intel version information after loading the FW */
23012417
err = btintel_read_version_tlv(hdev, &new_ver);
23022418
if (err)

drivers/bluetooth/btintel.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,19 @@ struct intel_offload_use_cases {
137137
__u8 preset[8];
138138
} __packed;
139139

140+
/* structure to store the PPAG data read from ACPI table */
141+
struct btintel_ppag {
142+
u32 domain;
143+
u32 mode;
144+
struct hci_dev *hdev;
145+
};
146+
147+
struct btintel_loc_aware_reg {
148+
__le32 mcc;
149+
__le32 sel;
150+
__le32 delta;
151+
} __packed;
152+
140153
#define INTEL_HW_PLATFORM(cnvx_bt) ((u8)(((cnvx_bt) & 0x0000ff00) >> 8))
141154
#define INTEL_HW_VARIANT(cnvx_bt) ((u8)(((cnvx_bt) & 0x003f0000) >> 16))
142155
#define INTEL_CNVX_TOP_TYPE(cnvx_top) ((cnvx_top) & 0x00000fff)

0 commit comments

Comments
 (0)