diff options
author | Jan200101 <sentrycraft123@gmail.com> | 2023-12-06 19:18:31 +0100 |
---|---|---|
committer | Jan200101 <sentrycraft123@gmail.com> | 2023-12-06 19:18:31 +0100 |
commit | 35570801b7384f86c61fccf98cdf080d82ffd182 (patch) | |
tree | da74997436cce94ba6a3530269fbeb6ef9d8cd98 /SOURCES/steamdeck-oled-bt.patch | |
parent | 6229f58d19ef9e8c060cc9d9974ef6fcf1bcb528 (diff) | |
download | kernel-fsync-35570801b7384f86c61fccf98cdf080d82ffd182.tar.gz kernel-fsync-35570801b7384f86c61fccf98cdf080d82ffd182.zip |
kernel 6.6.3
Diffstat (limited to 'SOURCES/steamdeck-oled-bt.patch')
-rw-r--r-- | SOURCES/steamdeck-oled-bt.patch | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/SOURCES/steamdeck-oled-bt.patch b/SOURCES/steamdeck-oled-bt.patch new file mode 100644 index 0000000..20cf681 --- /dev/null +++ b/SOURCES/steamdeck-oled-bt.patch @@ -0,0 +1,239 @@ +From fca3761de38864b0422006aaaf9ce8e0aba5e316 Mon Sep 17 00:00:00 2001 +From: Thomas Crider <gloriouseggroll@gmail.com> +Date: Sat, 2 Dec 2023 05:07:16 -0500 +Subject: [PATCH] steamdeck-bt-unified + +--- + drivers/bluetooth/btqca.c | 78 +++++++++++++++++++++++++++++++++++++ + drivers/bluetooth/btqca.h | 3 ++ + drivers/bluetooth/hci_qca.c | 9 ++++- + net/bluetooth/hci_sync.c | 10 +++-- + 4 files changed, 95 insertions(+), 5 deletions(-) + +diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c +index 5a35ac413..de2195b72 100644 +--- a/drivers/bluetooth/btqca.c ++++ b/drivers/bluetooth/btqca.c +@@ -205,6 +205,48 @@ static int qca_send_reset(struct hci_dev *hdev) + return 0; + } + ++static int qca_read_fw_board_id(struct hci_dev *hdev, u16 *bid) ++{ ++ u8 cmd; ++ struct sk_buff *skb; ++ struct edl_event_hdr *edl; ++ int err = 0; ++ int bid_len; ++ ++ bt_dev_dbg(hdev, "QCA read board ID"); ++ ++ cmd = EDL_GET_BID_REQ_CMD; ++ skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN, ++ &cmd, 0, HCI_INIT_TIMEOUT); ++ if (IS_ERR(skb)) { ++ err = PTR_ERR(skb); ++ bt_dev_err(hdev, "Reading QCA board ID failed (%d)", err); ++ return err; ++ } ++ ++ edl = skb_pull_data(skb, sizeof(*edl)); ++ if (!edl) { ++ bt_dev_err(hdev, "QCA read board ID with no header"); ++ err = -EILSEQ; ++ goto out; ++ } ++ ++ if (edl->cresp != EDL_CMD_REQ_RES_EVT || ++ edl->rtype != EDL_GET_BID_REQ_CMD) { ++ bt_dev_err(hdev, "QCA Wrong packet: %d %d", edl->cresp, edl->rtype); ++ err = -EIO; ++ goto out; ++ } ++ ++ bid_len = edl->data[0]; ++ *bid = (edl->data[1] << 8) + edl->data[2]; ++ bt_dev_info(hdev, "%s: bid len = %x, bid = %x", __func__, bid_len, *bid); ++ ++out: ++ kfree_skb(skb); ++ return err; ++} ++ + int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) + { + struct sk_buff *skb; +@@ -574,6 +616,30 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) + } + EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); + ++static void qca_generate_nvm_name(struct hci_dev *hdev, char *fwname, ++ size_t max_size, struct qca_btsoc_version ver, u16 bid) ++{ ++ u8 rom_ver = 0; ++ u32 soc_ver; ++ const char *variant; ++ ++ soc_ver = get_soc_ver(ver.soc_id, ver.rom_ver); ++ rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f); ++ ++ if ((ver.soc_id & 0x0000ff00) == QCA_HSP_GF_SOC_ID) /* hsp gf chip */ ++ variant = "g"; ++ else ++ variant = ""; ++ ++ if (bid == 0x0) ++ snprintf(fwname, max_size, "qca/hpnv%02x%s.bin", rom_ver, variant); ++ else ++ snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", ++ rom_ver, variant, bid); ++ ++ bt_dev_info(hdev, "%s: nvm name is %s", __func__, fwname); ++} ++ + int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + enum qca_btsoc_type soc_type, struct qca_btsoc_version ver, + const char *firmware_name) +@@ -582,6 +648,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + int err; + u8 rom_ver = 0; + u32 soc_ver; ++ u16 boardid = 0; + + bt_dev_dbg(hdev, "QCA setup on UART"); + +@@ -605,6 +672,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + /* Download rampatch file */ + config.type = TLV_TYPE_PATCH; + switch (soc_type) { ++ case QCA_QCA2066: ++ snprintf(config.fwname, sizeof(config.fwname), ++ "qca/hpbtfw%02x.tlv", rom_ver); ++ break; + case QCA_WCN3990: + case QCA_WCN3991: + case QCA_WCN3998: +@@ -649,6 +720,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + /* Give the controller some time to get ready to receive the NVM */ + msleep(10); + ++ if (soc_type == QCA_QCA2066) ++ qca_read_fw_board_id(hdev, &boardid); ++ + /* Download NVM configuration */ + config.type = TLV_TYPE_NVM; + if (firmware_name) { +@@ -656,6 +730,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + "qca/%s", firmware_name); + } else { + switch (soc_type) { ++ case QCA_QCA2066: ++ qca_generate_nvm_name(hdev, config.fwname, sizeof(config.fwname), ++ ver, boardid); ++ break; + case QCA_WCN3990: + case QCA_WCN3991: + case QCA_WCN3998: +diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h +index 03bff5c00..ffed9ea8a 100644 +--- a/drivers/bluetooth/btqca.h ++++ b/drivers/bluetooth/btqca.h +@@ -13,6 +13,7 @@ + #define EDL_PATCH_TLV_REQ_CMD (0x1E) + #define EDL_GET_BUILD_INFO_CMD (0x20) + #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) ++#define EDL_GET_BID_REQ_CMD (0x23) + #define EDL_PATCH_CONFIG_CMD (0x28) + #define MAX_SIZE_PER_TLV_SEGMENT (243) + #define QCA_PRE_SHUTDOWN_CMD (0xFC08) +@@ -48,6 +49,7 @@ + + #define QCA_FW_BUILD_VER_LEN 255 + ++#define QCA_HSP_GF_SOC_ID 0x1200 + + enum qca_baudrate { + QCA_BAUDRATE_115200 = 0, +@@ -146,6 +148,7 @@ enum qca_btsoc_type { + QCA_WCN3990, + QCA_WCN3998, + QCA_WCN3991, ++ QCA_QCA2066, + QCA_QCA6390, + QCA_WCN6750, + QCA_WCN6855, +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c +index 4b57e15f9..891c25ffc 100644 +--- a/drivers/bluetooth/hci_qca.c ++++ b/drivers/bluetooth/hci_qca.c +@@ -1861,7 +1861,7 @@ static int qca_setup(struct hci_uart *hu) + break; + + default: +- soc_name = "ROME/QCA6390"; ++ soc_name = "ROME/QCA6390/QCA2066"; + } + bt_dev_info(hdev, "setting up %s", soc_name); + +@@ -1987,6 +1987,11 @@ static const struct hci_uart_proto qca_proto = { + .dequeue = qca_dequeue, + }; + ++static const struct qca_device_data qca_soc_data_qca2066 = { ++ .soc_type = QCA_QCA2066, ++ .num_vregs = 0, ++}; ++ + static const struct qca_device_data qca_soc_data_wcn3988 __maybe_unused = { + .soc_type = QCA_WCN3988, + .vregs = (struct qca_vreg []) { +@@ -2569,6 +2574,7 @@ static const struct of_device_id qca_bluetooth_of_match[] = { + { .compatible = "qcom,wcn6750-bt", .data = &qca_soc_data_wcn6750}, + { .compatible = "qcom,wcn6855-bt", .data = &qca_soc_data_wcn6855}, + { .compatible = "qcom,wcn7850-bt", .data = &qca_soc_data_wcn7850}, ++ { .compatible = "qcom,qca2066-bt", .data = &qca_soc_data_qca2066}, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); +@@ -2580,6 +2586,7 @@ static const struct acpi_device_id qca_bluetooth_acpi_match[] = { + { "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, + { "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, + { "DLB26390", (kernel_ulong_t)&qca_soc_data_qca6390 }, ++ { "QCOM2066", (kernel_ulong_t)&qca_soc_data_qca2066 }, + { }, + }; + MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match); +diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c +index 9e71362c0..ac5c0cafd 100644 +--- a/net/bluetooth/hci_sync.c ++++ b/net/bluetooth/hci_sync.c +@@ -3800,12 +3800,14 @@ static int hci_set_event_mask_sync(struct hci_dev *hdev) + if (lmp_bredr_capable(hdev)) { + events[4] |= 0x01; /* Flow Specification Complete */ + +- /* Don't set Disconnect Complete when suspended as that +- * would wakeup the host when disconnecting due to ++ /* Don't set Disconnect Complete and mode change when suspended ++ * as that would wakeup the host when disconnecting due to + * suspend. + */ +- if (hdev->suspended) ++ if (hdev->suspended){ + events[0] &= 0xef; ++ events[2] &= 0xf7; ++ } + } else { + /* Use a different default for LE-only devices */ + memset(events, 0, sizeof(events)); +@@ -5931,7 +5933,7 @@ int hci_suspend_sync(struct hci_dev *hdev) + + if (hci_conn_count(hdev)) { + /* Soft disconnect everything (power off) */ +- err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_POWER_OFF); ++ err = hci_disconnect_all_sync(hdev, HCI_ERROR_REMOTE_USER_TERM); + if (err) { + /* Set state to BT_RUNNING so resume doesn't notify */ + hdev->suspend_state = BT_RUNNING; +-- +2.43.0 + |