|
| 1 | +From 30209aeff75fe18cf01a63332a7a7f472877d445 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Cheng Jiang < [email protected]> |
| 3 | +Date: Tue, 7 Jan 2025 17:26:50 +0800 |
| 4 | +Subject: [PATCH] Bluetooth: qca: Expand firmware-name to load specific |
| 5 | + rampatch |
| 6 | + |
| 7 | +The firmware-name property has been expanded to specify the names of NVM |
| 8 | +and rampatch firmware for certain chips, such as the QCA6698 Bluetooth |
| 9 | +chip. Although it shares the same IP core as the WCN6855, the QCA6698 |
| 10 | +has different RF components and RAM sizes, necessitating new firmware |
| 11 | +files. This change allows for the configuration of NVM and rampatch in |
| 12 | +DT. |
| 13 | + |
| 14 | +Possible configurations: |
| 15 | +firmware-name = QCA6698/hpnv21.bin, QCA6698/hpbtfw21.tlv; |
| 16 | +firmware-name = QCA6698/hpnv21, QCA6698/hpbtfw21.tlv; |
| 17 | + |
| 18 | +Signed-off-by: Cheng Jiang < [email protected]> |
| 19 | +Signed-off-by: Luiz Augusto von Dentz < [email protected]> |
| 20 | +Upstream-Status: Backport [https://git.kernel.org/bluetooth/bluetooth-next/c/30209aeff75f] |
| 21 | +--- |
| 22 | + drivers/bluetooth/btqca.c | 82 +++++++++++++++++++------------------ |
| 23 | + drivers/bluetooth/btqca.h | 5 ++- |
| 24 | + drivers/bluetooth/hci_qca.c | 22 +++++++--- |
| 25 | + 3 files changed, 63 insertions(+), 46 deletions(-) |
| 26 | + |
| 27 | +diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c |
| 28 | +index 5cb1fd1a0c7b..a6b53d1f23db 100644 |
| 29 | +--- a/drivers/bluetooth/btqca.c |
| 30 | ++++ b/drivers/bluetooth/btqca.c |
| 31 | +@@ -782,7 +782,7 @@ static void qca_get_nvm_name_by_board(char *fwname, size_t max_size, |
| 32 | + |
| 33 | + int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, |
| 34 | + enum qca_btsoc_type soc_type, struct qca_btsoc_version ver, |
| 35 | +- const char *firmware_name) |
| 36 | ++ const char *firmware_name, const char *rampatch_name) |
| 37 | + { |
| 38 | + struct qca_fw_config config = {}; |
| 39 | + int err; |
| 40 | +@@ -811,44 +811,48 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, |
| 41 | + |
| 42 | + /* Download rampatch file */ |
| 43 | + config.type = TLV_TYPE_PATCH; |
| 44 | +- switch (soc_type) { |
| 45 | +- case QCA_WCN3990: |
| 46 | +- case QCA_WCN3991: |
| 47 | +- case QCA_WCN3998: |
| 48 | +- snprintf(config.fwname, sizeof(config.fwname), |
| 49 | +- "qca/crbtfw%02x.tlv", rom_ver); |
| 50 | +- break; |
| 51 | +- case QCA_WCN3988: |
| 52 | +- snprintf(config.fwname, sizeof(config.fwname), |
| 53 | +- "qca/apbtfw%02x.tlv", rom_ver); |
| 54 | +- break; |
| 55 | +- case QCA_QCA2066: |
| 56 | +- snprintf(config.fwname, sizeof(config.fwname), |
| 57 | +- "qca/hpbtfw%02x.tlv", rom_ver); |
| 58 | +- break; |
| 59 | +- case QCA_QCA6390: |
| 60 | +- snprintf(config.fwname, sizeof(config.fwname), |
| 61 | +- "qca/htbtfw%02x.tlv", rom_ver); |
| 62 | +- break; |
| 63 | +- case QCA_WCN6750: |
| 64 | +- /* Choose mbn file by default.If mbn file is not found |
| 65 | +- * then choose tlv file |
| 66 | +- */ |
| 67 | +- config.type = ELF_TYPE_PATCH; |
| 68 | +- snprintf(config.fwname, sizeof(config.fwname), |
| 69 | +- "qca/msbtfw%02x.mbn", rom_ver); |
| 70 | +- break; |
| 71 | +- case QCA_WCN6855: |
| 72 | +- snprintf(config.fwname, sizeof(config.fwname), |
| 73 | +- "qca/hpbtfw%02x.tlv", rom_ver); |
| 74 | +- break; |
| 75 | +- case QCA_WCN7850: |
| 76 | +- snprintf(config.fwname, sizeof(config.fwname), |
| 77 | +- "qca/hmtbtfw%02x.tlv", rom_ver); |
| 78 | +- break; |
| 79 | +- default: |
| 80 | +- snprintf(config.fwname, sizeof(config.fwname), |
| 81 | +- "qca/rampatch_%08x.bin", soc_ver); |
| 82 | ++ if (rampatch_name) { |
| 83 | ++ snprintf(config.fwname, sizeof(config.fwname), "qca/%s", rampatch_name); |
| 84 | ++ } else { |
| 85 | ++ switch (soc_type) { |
| 86 | ++ case QCA_WCN3990: |
| 87 | ++ case QCA_WCN3991: |
| 88 | ++ case QCA_WCN3998: |
| 89 | ++ snprintf(config.fwname, sizeof(config.fwname), |
| 90 | ++ "qca/crbtfw%02x.tlv", rom_ver); |
| 91 | ++ break; |
| 92 | ++ case QCA_WCN3988: |
| 93 | ++ snprintf(config.fwname, sizeof(config.fwname), |
| 94 | ++ "qca/apbtfw%02x.tlv", rom_ver); |
| 95 | ++ break; |
| 96 | ++ case QCA_QCA2066: |
| 97 | ++ snprintf(config.fwname, sizeof(config.fwname), |
| 98 | ++ "qca/hpbtfw%02x.tlv", rom_ver); |
| 99 | ++ break; |
| 100 | ++ case QCA_QCA6390: |
| 101 | ++ snprintf(config.fwname, sizeof(config.fwname), |
| 102 | ++ "qca/htbtfw%02x.tlv", rom_ver); |
| 103 | ++ break; |
| 104 | ++ case QCA_WCN6750: |
| 105 | ++ /* Choose mbn file by default.If mbn file is not found |
| 106 | ++ * then choose tlv file |
| 107 | ++ */ |
| 108 | ++ config.type = ELF_TYPE_PATCH; |
| 109 | ++ snprintf(config.fwname, sizeof(config.fwname), |
| 110 | ++ "qca/msbtfw%02x.mbn", rom_ver); |
| 111 | ++ break; |
| 112 | ++ case QCA_WCN6855: |
| 113 | ++ snprintf(config.fwname, sizeof(config.fwname), |
| 114 | ++ "qca/hpbtfw%02x.tlv", rom_ver); |
| 115 | ++ break; |
| 116 | ++ case QCA_WCN7850: |
| 117 | ++ snprintf(config.fwname, sizeof(config.fwname), |
| 118 | ++ "qca/hmtbtfw%02x.tlv", rom_ver); |
| 119 | ++ break; |
| 120 | ++ default: |
| 121 | ++ snprintf(config.fwname, sizeof(config.fwname), |
| 122 | ++ "qca/rampatch_%08x.bin", soc_ver); |
| 123 | ++ } |
| 124 | + } |
| 125 | + |
| 126 | + err = qca_download_firmware(hdev, &config, soc_type, rom_ver); |
| 127 | +diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h |
| 128 | +index bb5207d7a8c7..9d28c8800225 100644 |
| 129 | +--- a/drivers/bluetooth/btqca.h |
| 130 | ++++ b/drivers/bluetooth/btqca.h |
| 131 | +@@ -161,7 +161,7 @@ enum qca_btsoc_type { |
| 132 | + int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr); |
| 133 | + int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, |
| 134 | + enum qca_btsoc_type soc_type, struct qca_btsoc_version ver, |
| 135 | +- const char *firmware_name); |
| 136 | ++ const char *firmware_name, const char *rampatch_name); |
| 137 | + int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver, |
| 138 | + enum qca_btsoc_type); |
| 139 | + int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); |
| 140 | +@@ -176,7 +176,8 @@ static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdad |
| 141 | + static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, |
| 142 | + enum qca_btsoc_type soc_type, |
| 143 | + struct qca_btsoc_version ver, |
| 144 | +- const char *firmware_name) |
| 145 | ++ const char *firmware_name, |
| 146 | ++ const char *rampatch_name) |
| 147 | + { |
| 148 | + return -EOPNOTSUPP; |
| 149 | + } |
| 150 | +diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c |
| 151 | +index 37129e6cb0eb..5d75087cca99 100644 |
| 152 | +--- a/drivers/bluetooth/hci_qca.c |
| 153 | ++++ b/drivers/bluetooth/hci_qca.c |
| 154 | +@@ -228,7 +228,7 @@ struct qca_serdev { |
| 155 | + u32 init_speed; |
| 156 | + u32 oper_speed; |
| 157 | + bool bdaddr_property_broken; |
| 158 | +- const char *firmware_name; |
| 159 | ++ const char *firmware_name[2]; |
| 160 | + }; |
| 161 | + |
| 162 | + static int qca_regulator_enable(struct qca_serdev *qcadev); |
| 163 | +@@ -258,7 +258,18 @@ static const char *qca_get_firmware_name(struct hci_uart *hu) |
| 164 | + if (hu->serdev) { |
| 165 | + struct qca_serdev *qsd = serdev_device_get_drvdata(hu->serdev); |
| 166 | + |
| 167 | +- return qsd->firmware_name; |
| 168 | ++ return qsd->firmware_name[0]; |
| 169 | ++ } else { |
| 170 | ++ return NULL; |
| 171 | ++ } |
| 172 | ++} |
| 173 | ++ |
| 174 | ++static const char *qca_get_rampatch_name(struct hci_uart *hu) |
| 175 | ++{ |
| 176 | ++ if (hu->serdev) { |
| 177 | ++ struct qca_serdev *qsd = serdev_device_get_drvdata(hu->serdev); |
| 178 | ++ |
| 179 | ++ return qsd->firmware_name[1]; |
| 180 | + } else { |
| 181 | + return NULL; |
| 182 | + } |
| 183 | +@@ -1855,6 +1866,7 @@ static int qca_setup(struct hci_uart *hu) |
| 184 | + unsigned int retries = 0; |
| 185 | + enum qca_btsoc_type soc_type = qca_soc_type(hu); |
| 186 | + const char *firmware_name = qca_get_firmware_name(hu); |
| 187 | ++ const char *rampatch_name = qca_get_rampatch_name(hu); |
| 188 | + int ret; |
| 189 | + struct qca_btsoc_version ver; |
| 190 | + struct qca_serdev *qcadev; |
| 191 | +@@ -1963,7 +1975,7 @@ static int qca_setup(struct hci_uart *hu) |
| 192 | + |
| 193 | + /* Setup patch / NVM configurations */ |
| 194 | + ret = qca_uart_setup(hdev, qca_baudrate, soc_type, ver, |
| 195 | +- firmware_name); |
| 196 | ++ firmware_name, rampatch_name); |
| 197 | + if (!ret) { |
| 198 | + clear_bit(QCA_IBS_DISABLED, &qca->flags); |
| 199 | + qca_debugfs_init(hdev); |
| 200 | +@@ -2309,8 +2321,8 @@ static int qca_serdev_probe(struct serdev_device *serdev) |
| 201 | + qcadev->serdev_hu.serdev = serdev; |
| 202 | + data = device_get_match_data(&serdev->dev); |
| 203 | + serdev_device_set_drvdata(serdev, qcadev); |
| 204 | +- device_property_read_string(&serdev->dev, "firmware-name", |
| 205 | +- &qcadev->firmware_name); |
| 206 | ++ device_property_read_string_array(&serdev->dev, "firmware-name", |
| 207 | ++ qcadev->firmware_name, ARRAY_SIZE(qcadev->firmware_name)); |
| 208 | + device_property_read_u32(&serdev->dev, "max-speed", |
| 209 | + &qcadev->oper_speed); |
| 210 | + if (!qcadev->oper_speed) |
| 211 | +-- |
| 212 | +2.39.5 |
| 213 | + |
0 commit comments