Skip to content

Commit 095327f

Browse files
0x011011110Vudentz
authored andcommitted
Bluetooth: hci_qca: Add support for QTI Bluetooth chip wcn6855
Add regulators, GPIOs and changes required to power on/off wcn6855. Add support for firmware download for wcn6855 which is in the linux-firmware repository as hpbtfw21.tlv and hpnv21.bin. Based on the assumption that this is similar to the wcn6750 Tested-on: BTFW.HSP.2.1.0-00538-VER_PATCHZ-1 Signed-off-by: Steev Klimaszewski <[email protected]> Reviewed-by: Bjorn Andersson <[email protected]> Tested-by: Bjorn Andersson <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent b1d00ba commit 095327f

File tree

3 files changed

+66
-15
lines changed

3 files changed

+66
-15
lines changed

drivers/bluetooth/btqca.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
614614
config.type = ELF_TYPE_PATCH;
615615
snprintf(config.fwname, sizeof(config.fwname),
616616
"qca/msbtfw%02x.mbn", rom_ver);
617+
} else if (soc_type == QCA_WCN6855) {
618+
snprintf(config.fwname, sizeof(config.fwname),
619+
"qca/hpbtfw%02x.tlv", rom_ver);
617620
} else {
618621
snprintf(config.fwname, sizeof(config.fwname),
619622
"qca/rampatch_%08x.bin", soc_ver);
@@ -648,6 +651,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
648651
else if (soc_type == QCA_WCN6750)
649652
snprintf(config.fwname, sizeof(config.fwname),
650653
"qca/msnv%02x.bin", rom_ver);
654+
else if (soc_type == QCA_WCN6855)
655+
snprintf(config.fwname, sizeof(config.fwname),
656+
"qca/hpnv%02x.bin", rom_ver);
651657
else
652658
snprintf(config.fwname, sizeof(config.fwname),
653659
"qca/nvm_%08x.bin", soc_ver);
@@ -685,11 +691,17 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
685691
return err;
686692
}
687693

688-
if (soc_type == QCA_WCN3991 || soc_type == QCA_WCN6750) {
694+
switch (soc_type) {
695+
case QCA_WCN3991:
696+
case QCA_WCN6750:
697+
case QCA_WCN6855:
689698
/* get fw build info */
690699
err = qca_read_fw_build_info(hdev);
691700
if (err < 0)
692701
return err;
702+
break;
703+
default:
704+
break;
693705
}
694706

695707
bt_dev_info(hdev, "QCA setup on UART is completed");

drivers/bluetooth/btqca.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ enum qca_btsoc_type {
147147
QCA_WCN3991,
148148
QCA_QCA6390,
149149
QCA_WCN6750,
150+
QCA_WCN6855,
150151
};
151152

152153
#if IS_ENABLED(CONFIG_BT_QCA)
@@ -168,6 +169,10 @@ static inline bool qca_is_wcn6750(enum qca_btsoc_type soc_type)
168169
{
169170
return soc_type == QCA_WCN6750;
170171
}
172+
static inline bool qca_is_wcn6855(enum qca_btsoc_type soc_type)
173+
{
174+
return soc_type == QCA_WCN6855;
175+
}
171176

172177
#else
173178

@@ -206,6 +211,11 @@ static inline bool qca_is_wcn6750(enum qca_btsoc_type soc_type)
206211
return false;
207212
}
208213

214+
static inline bool qca_is_wcn6855(enum qca_btsoc_type soc_type)
215+
{
216+
return false;
217+
}
218+
209219
static inline int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
210220
{
211221
return -EOPNOTSUPP;

drivers/bluetooth/hci_qca.c

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,8 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
13171317

13181318
/* Give the controller time to process the request */
13191319
if (qca_is_wcn399x(qca_soc_type(hu)) ||
1320-
qca_is_wcn6750(qca_soc_type(hu)))
1320+
qca_is_wcn6750(qca_soc_type(hu)) ||
1321+
qca_is_wcn6855(qca_soc_type(hu)))
13211322
usleep_range(1000, 10000);
13221323
else
13231324
msleep(300);
@@ -1394,7 +1395,8 @@ static unsigned int qca_get_speed(struct hci_uart *hu,
13941395
static int qca_check_speeds(struct hci_uart *hu)
13951396
{
13961397
if (qca_is_wcn399x(qca_soc_type(hu)) ||
1397-
qca_is_wcn6750(qca_soc_type(hu))) {
1398+
qca_is_wcn6750(qca_soc_type(hu)) ||
1399+
qca_is_wcn6855(qca_soc_type(hu))) {
13981400
if (!qca_get_speed(hu, QCA_INIT_SPEED) &&
13991401
!qca_get_speed(hu, QCA_OPER_SPEED))
14001402
return -EINVAL;
@@ -1428,7 +1430,8 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
14281430
* changing the baudrate of chip and host.
14291431
*/
14301432
if (qca_is_wcn399x(soc_type) ||
1431-
qca_is_wcn6750(soc_type))
1433+
qca_is_wcn6750(soc_type) ||
1434+
qca_is_wcn6855(soc_type))
14321435
hci_uart_set_flow_control(hu, true);
14331436

14341437
if (soc_type == QCA_WCN3990) {
@@ -1446,7 +1449,8 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
14461449

14471450
error:
14481451
if (qca_is_wcn399x(soc_type) ||
1449-
qca_is_wcn6750(soc_type))
1452+
qca_is_wcn6750(soc_type) ||
1453+
qca_is_wcn6855(soc_type))
14501454
hci_uart_set_flow_control(hu, false);
14511455

14521456
if (soc_type == QCA_WCN3990) {
@@ -1682,7 +1686,8 @@ static int qca_power_on(struct hci_dev *hdev)
16821686
return 0;
16831687

16841688
if (qca_is_wcn399x(soc_type) ||
1685-
qca_is_wcn6750(soc_type)) {
1689+
qca_is_wcn6750(soc_type) ||
1690+
qca_is_wcn6855(soc_type)) {
16861691
ret = qca_regulator_init(hu);
16871692
} else {
16881693
qcadev = serdev_device_get_drvdata(hu->serdev);
@@ -1723,7 +1728,8 @@ static int qca_setup(struct hci_uart *hu)
17231728

17241729
bt_dev_info(hdev, "setting up %s",
17251730
qca_is_wcn399x(soc_type) ? "wcn399x" :
1726-
(soc_type == QCA_WCN6750) ? "wcn6750" : "ROME/QCA6390");
1731+
(soc_type == QCA_WCN6750) ? "wcn6750" :
1732+
(soc_type == QCA_WCN6855) ? "wcn6855" : "ROME/QCA6390");
17271733

17281734
qca->memdump_state = QCA_MEMDUMP_IDLE;
17291735

@@ -1735,7 +1741,8 @@ static int qca_setup(struct hci_uart *hu)
17351741
clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
17361742

17371743
if (qca_is_wcn399x(soc_type) ||
1738-
qca_is_wcn6750(soc_type)) {
1744+
qca_is_wcn6750(soc_type) ||
1745+
qca_is_wcn6855(soc_type)) {
17391746
set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
17401747
hci_set_aosp_capable(hdev);
17411748

@@ -1757,7 +1764,8 @@ static int qca_setup(struct hci_uart *hu)
17571764
}
17581765

17591766
if (!(qca_is_wcn399x(soc_type) ||
1760-
qca_is_wcn6750(soc_type))) {
1767+
qca_is_wcn6750(soc_type) ||
1768+
qca_is_wcn6855(soc_type))) {
17611769
/* Get QCA version information */
17621770
ret = qca_read_soc_version(hdev, &ver, soc_type);
17631771
if (ret)
@@ -1883,6 +1891,20 @@ static const struct qca_device_data qca_soc_data_wcn6750 __maybe_unused = {
18831891
.capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES,
18841892
};
18851893

1894+
static const struct qca_device_data qca_soc_data_wcn6855 = {
1895+
.soc_type = QCA_WCN6855,
1896+
.vregs = (struct qca_vreg []) {
1897+
{ "vddio", 5000 },
1898+
{ "vddbtcxmx", 126000 },
1899+
{ "vddrfacmn", 12500 },
1900+
{ "vddrfa0p8", 102000 },
1901+
{ "vddrfa1p7", 302000 },
1902+
{ "vddrfa1p2", 257000 },
1903+
},
1904+
.num_vregs = 6,
1905+
.capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES,
1906+
};
1907+
18861908
static void qca_power_shutdown(struct hci_uart *hu)
18871909
{
18881910
struct qca_serdev *qcadev;
@@ -1912,7 +1934,7 @@ static void qca_power_shutdown(struct hci_uart *hu)
19121934
host_set_baudrate(hu, 2400);
19131935
qca_send_power_pulse(hu, false);
19141936
qca_regulator_disable(qcadev);
1915-
} else if (soc_type == QCA_WCN6750) {
1937+
} else if (soc_type == QCA_WCN6750 || soc_type == QCA_WCN6855) {
19161938
gpiod_set_value_cansleep(qcadev->bt_en, 0);
19171939
msleep(100);
19181940
qca_regulator_disable(qcadev);
@@ -2047,7 +2069,8 @@ static int qca_serdev_probe(struct serdev_device *serdev)
20472069

20482070
if (data &&
20492071
(qca_is_wcn399x(data->soc_type) ||
2050-
qca_is_wcn6750(data->soc_type))) {
2072+
qca_is_wcn6750(data->soc_type) ||
2073+
qca_is_wcn6855(data->soc_type))) {
20512074
qcadev->btsoc_type = data->soc_type;
20522075
qcadev->bt_power = devm_kzalloc(&serdev->dev,
20532076
sizeof(struct qca_power),
@@ -2067,14 +2090,18 @@ static int qca_serdev_probe(struct serdev_device *serdev)
20672090

20682091
qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
20692092
GPIOD_OUT_LOW);
2070-
if (IS_ERR_OR_NULL(qcadev->bt_en) && data->soc_type == QCA_WCN6750) {
2093+
if (IS_ERR_OR_NULL(qcadev->bt_en) &&
2094+
(data->soc_type == QCA_WCN6750 ||
2095+
data->soc_type == QCA_WCN6855)) {
20712096
dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n");
20722097
power_ctrl_enabled = false;
20732098
}
20742099

20752100
qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl",
20762101
GPIOD_IN);
2077-
if (IS_ERR_OR_NULL(qcadev->sw_ctrl) && data->soc_type == QCA_WCN6750)
2102+
if (IS_ERR_OR_NULL(qcadev->sw_ctrl) &&
2103+
(data->soc_type == QCA_WCN6750 ||
2104+
data->soc_type == QCA_WCN6855))
20782105
dev_warn(&serdev->dev, "failed to acquire SW_CTRL gpio\n");
20792106

20802107
qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL);
@@ -2150,8 +2177,9 @@ static void qca_serdev_remove(struct serdev_device *serdev)
21502177
struct qca_power *power = qcadev->bt_power;
21512178

21522179
if ((qca_is_wcn399x(qcadev->btsoc_type) ||
2153-
qca_is_wcn6750(qcadev->btsoc_type)) &&
2154-
power->vregs_on)
2180+
qca_is_wcn6750(qcadev->btsoc_type) ||
2181+
qca_is_wcn6855(qcadev->btsoc_type)) &&
2182+
power->vregs_on)
21552183
qca_power_shutdown(&qcadev->serdev_hu);
21562184
else if (qcadev->susclk)
21572185
clk_disable_unprepare(qcadev->susclk);
@@ -2335,6 +2363,7 @@ static const struct of_device_id qca_bluetooth_of_match[] = {
23352363
{ .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991},
23362364
{ .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998},
23372365
{ .compatible = "qcom,wcn6750-bt", .data = &qca_soc_data_wcn6750},
2366+
{ .compatible = "qcom,wcn6855-bt", .data = &qca_soc_data_wcn6855},
23382367
{ /* sentinel */ }
23392368
};
23402369
MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);

0 commit comments

Comments
 (0)