]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Bluetooth: qca: Expand firmware-name to load specific rampatch
authorCheng Jiang <quic_chejiang@quicinc.com>
Tue, 7 Jan 2025 09:26:50 +0000 (17:26 +0800)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 15 Jan 2025 15:34:12 +0000 (10:34 -0500)
The firmware-name property has been expanded to specify the names of NVM
and rampatch firmware for certain chips, such as the QCA6698 Bluetooth
chip. Although it shares the same IP core as the WCN6855, the QCA6698
has different RF components and RAM sizes, necessitating new firmware
files. This change allows for the configuration of NVM and rampatch in
DT.

Possible configurations:
firmware-name = QCA6698/hpnv21.bin, QCA6698/hpbtfw21.tlv;
firmware-name = QCA6698/hpnv21, QCA6698/hpbtfw21.tlv;

Signed-off-by: Cheng Jiang <quic_chejiang@quicinc.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
drivers/bluetooth/btqca.c
drivers/bluetooth/btqca.h
drivers/bluetooth/hci_qca.c

index 5cb1fd1a0c7b5ff4320f0a7025c826bd2c55df2e..a6b53d1f23dbd4666b93e10635f5f154f38d80a5 100644 (file)
@@ -782,7 +782,7 @@ static void qca_get_nvm_name_by_board(char *fwname, size_t max_size,
 
 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)
+                  const char *firmware_name, const char *rampatch_name)
 {
        struct qca_fw_config config = {};
        int err;
@@ -811,44 +811,48 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 
        /* Download rampatch file */
        config.type = TLV_TYPE_PATCH;
-       switch (soc_type) {
-       case QCA_WCN3990:
-       case QCA_WCN3991:
-       case QCA_WCN3998:
-               snprintf(config.fwname, sizeof(config.fwname),
-                        "qca/crbtfw%02x.tlv", rom_ver);
-               break;
-       case QCA_WCN3988:
-               snprintf(config.fwname, sizeof(config.fwname),
-                        "qca/apbtfw%02x.tlv", rom_ver);
-               break;
-       case QCA_QCA2066:
-               snprintf(config.fwname, sizeof(config.fwname),
-                        "qca/hpbtfw%02x.tlv", rom_ver);
-               break;
-       case QCA_QCA6390:
-               snprintf(config.fwname, sizeof(config.fwname),
-                        "qca/htbtfw%02x.tlv", rom_ver);
-               break;
-       case QCA_WCN6750:
-               /* Choose mbn file by default.If mbn file is not found
-                * then choose tlv file
-                */
-               config.type = ELF_TYPE_PATCH;
-               snprintf(config.fwname, sizeof(config.fwname),
-                        "qca/msbtfw%02x.mbn", rom_ver);
-               break;
-       case QCA_WCN6855:
-               snprintf(config.fwname, sizeof(config.fwname),
-                        "qca/hpbtfw%02x.tlv", rom_ver);
-               break;
-       case QCA_WCN7850:
-               snprintf(config.fwname, sizeof(config.fwname),
-                        "qca/hmtbtfw%02x.tlv", rom_ver);
-               break;
-       default:
-               snprintf(config.fwname, sizeof(config.fwname),
-                        "qca/rampatch_%08x.bin", soc_ver);
+       if (rampatch_name) {
+               snprintf(config.fwname, sizeof(config.fwname), "qca/%s", rampatch_name);
+       } else {
+               switch (soc_type) {
+               case QCA_WCN3990:
+               case QCA_WCN3991:
+               case QCA_WCN3998:
+                       snprintf(config.fwname, sizeof(config.fwname),
+                                "qca/crbtfw%02x.tlv", rom_ver);
+                       break;
+               case QCA_WCN3988:
+                       snprintf(config.fwname, sizeof(config.fwname),
+                                "qca/apbtfw%02x.tlv", rom_ver);
+                       break;
+               case QCA_QCA2066:
+                       snprintf(config.fwname, sizeof(config.fwname),
+                                "qca/hpbtfw%02x.tlv", rom_ver);
+                       break;
+               case QCA_QCA6390:
+                       snprintf(config.fwname, sizeof(config.fwname),
+                                "qca/htbtfw%02x.tlv", rom_ver);
+                       break;
+               case QCA_WCN6750:
+                       /* Choose mbn file by default.If mbn file is not found
+                        * then choose tlv file
+                        */
+                       config.type = ELF_TYPE_PATCH;
+                       snprintf(config.fwname, sizeof(config.fwname),
+                                "qca/msbtfw%02x.mbn", rom_ver);
+                       break;
+               case QCA_WCN6855:
+                       snprintf(config.fwname, sizeof(config.fwname),
+                                "qca/hpbtfw%02x.tlv", rom_ver);
+                       break;
+               case QCA_WCN7850:
+                       snprintf(config.fwname, sizeof(config.fwname),
+                                "qca/hmtbtfw%02x.tlv", rom_ver);
+                       break;
+               default:
+                       snprintf(config.fwname, sizeof(config.fwname),
+                                "qca/rampatch_%08x.bin", soc_ver);
+               }
        }
 
        err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
index bb5207d7a8c72cbf3dc468d61f80483ffb6e2ab1..9d28c88002257bae31249457b98a5df1df26efe4 100644 (file)
@@ -161,7 +161,7 @@ enum qca_btsoc_type {
 int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 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);
+                  const char *firmware_name, const char *rampatch_name);
 int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
                         enum qca_btsoc_type);
 int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
@@ -176,7 +176,8 @@ static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdad
 static inline 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)
+                                const char *firmware_name,
+                                const char *rampatch_name)
 {
        return -EOPNOTSUPP;
 }
index 37129e6cb0eb136e2e356b9f4a03e1da700e00c1..5d75087cca9981774eeff8115ce261bbd29508f9 100644 (file)
@@ -228,7 +228,7 @@ struct qca_serdev {
        u32 init_speed;
        u32 oper_speed;
        bool bdaddr_property_broken;
-       const char *firmware_name;
+       const char *firmware_name[2];
 };
 
 static int qca_regulator_enable(struct qca_serdev *qcadev);
@@ -258,7 +258,18 @@ static const char *qca_get_firmware_name(struct hci_uart *hu)
        if (hu->serdev) {
                struct qca_serdev *qsd = serdev_device_get_drvdata(hu->serdev);
 
-               return qsd->firmware_name;
+               return qsd->firmware_name[0];
+       } else {
+               return NULL;
+       }
+}
+
+static const char *qca_get_rampatch_name(struct hci_uart *hu)
+{
+       if (hu->serdev) {
+               struct qca_serdev *qsd = serdev_device_get_drvdata(hu->serdev);
+
+               return qsd->firmware_name[1];
        } else {
                return NULL;
        }
@@ -1855,6 +1866,7 @@ static int qca_setup(struct hci_uart *hu)
        unsigned int retries = 0;
        enum qca_btsoc_type soc_type = qca_soc_type(hu);
        const char *firmware_name = qca_get_firmware_name(hu);
+       const char *rampatch_name = qca_get_rampatch_name(hu);
        int ret;
        struct qca_btsoc_version ver;
        struct qca_serdev *qcadev;
@@ -1963,7 +1975,7 @@ retry:
 
        /* Setup patch / NVM configurations */
        ret = qca_uart_setup(hdev, qca_baudrate, soc_type, ver,
-                       firmware_name);
+                       firmware_name, rampatch_name);
        if (!ret) {
                clear_bit(QCA_IBS_DISABLED, &qca->flags);
                qca_debugfs_init(hdev);
@@ -2309,8 +2321,8 @@ static int qca_serdev_probe(struct serdev_device *serdev)
        qcadev->serdev_hu.serdev = serdev;
        data = device_get_match_data(&serdev->dev);
        serdev_device_set_drvdata(serdev, qcadev);
-       device_property_read_string(&serdev->dev, "firmware-name",
-                                        &qcadev->firmware_name);
+       device_property_read_string_array(&serdev->dev, "firmware-name",
+                                        qcadev->firmware_name, ARRAY_SIZE(qcadev->firmware_name));
        device_property_read_u32(&serdev->dev, "max-speed",
                                 &qcadev->oper_speed);
        if (!qcadev->oper_speed)