diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 6ce5c8835efe..8b33128dccee 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -356,7 +356,8 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, - enum qca_btsoc_type soc_type, u32 soc_ver) + enum qca_btsoc_type soc_type, u32 soc_ver, + const char *firmware_name) { struct rome_config config; int err; @@ -389,7 +390,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, /* Download NVM configuration */ config.type = TLV_TYPE_NVM; - if (qca_is_wcn399x(soc_type)) + if (firmware_name) + snprintf(config.fwname, sizeof(config.fwname), + "qca/%s", firmware_name); + else if (qca_is_wcn399x(soc_type)) snprintf(config.fwname, sizeof(config.fwname), "qca/crnv%02x.bin", rom_ver); else diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index 03fdec20730b..6a291a7a5d96 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -131,7 +131,8 @@ 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, u32 soc_ver); + enum qca_btsoc_type soc_type, u32 soc_ver, + const char *firmware_name); int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version); int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) @@ -146,7 +147,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, u32 soc_ver) + enum qca_btsoc_type soc_type, u32 soc_ver, + const char *firmware_name) { return -EOPNOTSUPP; } diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 9f992b905f24..9a5c9c1f9484 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -159,6 +159,7 @@ struct qca_serdev { struct qca_power *bt_power; u32 init_speed; u32 oper_speed; + const char *firmware_name; }; static int qca_power_setup(struct hci_uart *hu, bool on); @@ -180,6 +181,17 @@ static enum qca_btsoc_type qca_soc_type(struct hci_uart *hu) return soc_type; } +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; + } else { + return NULL; + } +} + static void __serial_clock_on(struct tty_struct *tty) { /* TODO: Some chipset requires to enable UART clock on client @@ -1235,6 +1247,7 @@ static int qca_setup(struct hci_uart *hu) struct qca_data *qca = hu->priv; unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200; enum qca_btsoc_type soc_type = qca_soc_type(hu); + const char *firmware_name = qca_get_firmware_name(hu); int ret; int soc_ver = 0; @@ -1285,7 +1298,8 @@ static int qca_setup(struct hci_uart *hu) bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver); /* Setup patch / NVM configurations */ - ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver); + ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver, + firmware_name); if (!ret) { set_bit(QCA_IBS_ENABLED, &qca->flags); qca_debugfs_init(hdev); @@ -1479,6 +1493,8 @@ static int qca_serdev_probe(struct serdev_device *serdev) qcadev->serdev_hu.serdev = serdev; data = of_device_get_match_data(&serdev->dev); serdev_device_set_drvdata(serdev, qcadev); + device_property_read_string(&serdev->dev, "firmware-name", + &qcadev->firmware_name); if (data && qca_is_wcn399x(data->soc_type)) { qcadev->btsoc_type = data->soc_type; qcadev->bt_power = devm_kzalloc(&serdev->dev,