summaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorRocky Liao <rjliao@codeaurora.org>2019-06-06 05:40:30 -0400
committerMarcel Holtmann <marcel@holtmann.org>2019-07-06 06:55:39 -0400
commit99c905c6a165a590780a961988892bfec41566dd (patch)
treefc394ec73d03950a1c1eda0af71bdce2c86be700 /drivers/bluetooth
parentbe70e5e774a616ad43e63c0b42c2f6e2709dbf3b (diff)
Bluetooth: hci_qca: Load customized NVM based on the device property
QCA BTSOC NVM is a customized firmware file and different vendors may want to have different BTSOC configuration (e.g. Configure SCO over PCM or I2S, Setting Tx power, etc.) via this file. This patch will allow vendors to download different NVM firmware file by reading a device property "firmware-name". Signed-off-by: Rocky Liao <rjliao@codeaurora.org> Tested-by: Harish Bandi <c-hbandi@codeaurora.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/btqca.c8
-rw-r--r--drivers/bluetooth/btqca.h6
-rw-r--r--drivers/bluetooth/hci_qca.c18
3 files changed, 27 insertions, 5 deletions
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)
356EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); 356EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);
357 357
358int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, 358int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
359 enum qca_btsoc_type soc_type, u32 soc_ver) 359 enum qca_btsoc_type soc_type, u32 soc_ver,
360 const char *firmware_name)
360{ 361{
361 struct rome_config config; 362 struct rome_config config;
362 int err; 363 int err;
@@ -389,7 +390,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
389 390
390 /* Download NVM configuration */ 391 /* Download NVM configuration */
391 config.type = TLV_TYPE_NVM; 392 config.type = TLV_TYPE_NVM;
392 if (qca_is_wcn399x(soc_type)) 393 if (firmware_name)
394 snprintf(config.fwname, sizeof(config.fwname),
395 "qca/%s", firmware_name);
396 else if (qca_is_wcn399x(soc_type))
393 snprintf(config.fwname, sizeof(config.fwname), 397 snprintf(config.fwname, sizeof(config.fwname),
394 "qca/crnv%02x.bin", rom_ver); 398 "qca/crnv%02x.bin", rom_ver);
395 else 399 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 {
131 131
132int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr); 132int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr);
133int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, 133int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
134 enum qca_btsoc_type soc_type, u32 soc_ver); 134 enum qca_btsoc_type soc_type, u32 soc_ver,
135 const char *firmware_name);
135int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version); 136int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version);
136int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); 137int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
137static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) 138static 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
146} 147}
147 148
148static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, 149static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
149 enum qca_btsoc_type soc_type, u32 soc_ver) 150 enum qca_btsoc_type soc_type, u32 soc_ver,
151 const char *firmware_name)
150{ 152{
151 return -EOPNOTSUPP; 153 return -EOPNOTSUPP;
152} 154}
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 {
159 struct qca_power *bt_power; 159 struct qca_power *bt_power;
160 u32 init_speed; 160 u32 init_speed;
161 u32 oper_speed; 161 u32 oper_speed;
162 const char *firmware_name;
162}; 163};
163 164
164static int qca_power_setup(struct hci_uart *hu, bool on); 165static 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)
180 return soc_type; 181 return soc_type;
181} 182}
182 183
184static const char *qca_get_firmware_name(struct hci_uart *hu)
185{
186 if (hu->serdev) {
187 struct qca_serdev *qsd = serdev_device_get_drvdata(hu->serdev);
188
189 return qsd->firmware_name;
190 } else {
191 return NULL;
192 }
193}
194
183static void __serial_clock_on(struct tty_struct *tty) 195static void __serial_clock_on(struct tty_struct *tty)
184{ 196{
185 /* TODO: Some chipset requires to enable UART clock on client 197 /* TODO: Some chipset requires to enable UART clock on client
@@ -1235,6 +1247,7 @@ static int qca_setup(struct hci_uart *hu)
1235 struct qca_data *qca = hu->priv; 1247 struct qca_data *qca = hu->priv;
1236 unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200; 1248 unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200;
1237 enum qca_btsoc_type soc_type = qca_soc_type(hu); 1249 enum qca_btsoc_type soc_type = qca_soc_type(hu);
1250 const char *firmware_name = qca_get_firmware_name(hu);
1238 int ret; 1251 int ret;
1239 int soc_ver = 0; 1252 int soc_ver = 0;
1240 1253
@@ -1285,7 +1298,8 @@ static int qca_setup(struct hci_uart *hu)
1285 1298
1286 bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver); 1299 bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver);
1287 /* Setup patch / NVM configurations */ 1300 /* Setup patch / NVM configurations */
1288 ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver); 1301 ret = qca_uart_setup(hdev, qca_baudrate, soc_type, soc_ver,
1302 firmware_name);
1289 if (!ret) { 1303 if (!ret) {
1290 set_bit(QCA_IBS_ENABLED, &qca->flags); 1304 set_bit(QCA_IBS_ENABLED, &qca->flags);
1291 qca_debugfs_init(hdev); 1305 qca_debugfs_init(hdev);
@@ -1479,6 +1493,8 @@ static int qca_serdev_probe(struct serdev_device *serdev)
1479 qcadev->serdev_hu.serdev = serdev; 1493 qcadev->serdev_hu.serdev = serdev;
1480 data = of_device_get_match_data(&serdev->dev); 1494 data = of_device_get_match_data(&serdev->dev);
1481 serdev_device_set_drvdata(serdev, qcadev); 1495 serdev_device_set_drvdata(serdev, qcadev);
1496 device_property_read_string(&serdev->dev, "firmware-name",
1497 &qcadev->firmware_name);
1482 if (data && qca_is_wcn399x(data->soc_type)) { 1498 if (data && qca_is_wcn399x(data->soc_type)) {
1483 qcadev->btsoc_type = data->soc_type; 1499 qcadev->btsoc_type = data->soc_type;
1484 qcadev->bt_power = devm_kzalloc(&serdev->dev, 1500 qcadev->bt_power = devm_kzalloc(&serdev->dev,