* Re: [PATCH v1 1/2] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390 [not found] <0101016ef8b72eb9-c2212883-72cf-4f02-9f5d-078135c7085e-000000@us-west-2.amazonses.com> @ 2019-12-12 10:32 ` Marcel Holtmann 2019-12-13 3:33 ` rjliao 0 siblings, 1 reply; 8+ messages in thread From: Marcel Holtmann @ 2019-12-12 10:32 UTC (permalink / raw) To: Rocky Liao; +Cc: Johan Hedberg, lkml, linux-bluetooth Hi Rocky, > This patch add support for QCA6390. can we please be a bit more descriptive on what support we are adding. > > Signed-off-by: Rocky Liao <rjliao@codeaurora.org> > --- > drivers/bluetooth/btqca.c | 32 +++++++++++++++++++++-------- > drivers/bluetooth/btqca.h | 1 + > drivers/bluetooth/hci_qca.c | 40 ++++++++++++++++++++++++++++++++++--- > 3 files changed, 62 insertions(+), 11 deletions(-) > > diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c > index ec69e5dd7bd3..75990223e5e3 100644 > --- a/drivers/bluetooth/btqca.c > +++ b/drivers/bluetooth/btqca.c > @@ -13,6 +13,8 @@ > #include "btqca.h" > > #define VERSION "0.1" Lets put an extra empty line here. > +#define QCA_IS_3991_6390(soc_type) \ > + ((soc_type == QCA_WCN3991) || (soc_type == QCA_QCA6390)) Actually (a == b || c == d) is enough. I rather do ((a) == b || (c) == d) to ensure the parameter is properly protected. It is not needed in this case since the usage is simple. > > int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, > enum qca_btsoc_type soc_type) > @@ -32,7 +34,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, > * VSE event. WCN3991 sends version command response as a payload to > * command complete event. > */ > - if (soc_type == QCA_WCN3991) { > + if (QCA_IS_3991_6390(soc_type)) { > event_type = 0; > rlen += 1; > rtype = EDL_PATCH_VER_REQ_CMD; > @@ -69,7 +71,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, > goto out; > } > > - if (soc_type == QCA_WCN3991) > + if ((QCA_IS_3991_6390(soc_type))) > memmove(&edl->data, &edl->data[1], sizeof(*ver)); Maybe these should just be turned into a switch statement and not using some macro. > > ver = (struct qca_btsoc_version *)(edl->data); > @@ -139,7 +141,7 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) > EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); > > static void qca_tlv_check_data(struct qca_fw_config *config, > - const struct firmware *fw) > + const struct firmware *fw, enum qca_btsoc_type soc_type) > { > const u8 *data; > u32 type_len; > @@ -148,6 +150,7 @@ static void qca_tlv_check_data(struct qca_fw_config *config, > struct tlv_type_hdr *tlv; > struct tlv_type_patch *tlv_patch; > struct tlv_type_nvm *tlv_nvm; > + uint8_t nvm_baud_rate = config->user_baud_rate; > > tlv = (struct tlv_type_hdr *)fw->data; > > @@ -213,10 +216,14 @@ static void qca_tlv_check_data(struct qca_fw_config *config, > * enabling software inband sleep > * onto controller side. > */ > - tlv_nvm->data[0] |= 0x80; > + if (!QCA_IS_3991_6390(soc_type)) > + tlv_nvm->data[0] |= 0x80; > > /* UART Baud Rate */ > - tlv_nvm->data[2] = config->user_baud_rate; > + if ((QCA_IS_3991_6390(soc_type))) > + tlv_nvm->data[1] = nvm_baud_rate; > + else > + tlv_nvm->data[2] = nvm_baud_rate; These two changes are not related to the QCA6390 support. Leave them out and if changes are needed to fix other hardware, then send them as separate patch. > > break; > > @@ -264,7 +271,7 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, > * VSE event. WCN3991 sends version command response as a payload to > * command complete event. > */ > - if (soc_type == QCA_WCN3991) { > + if ((QCA_IS_3991_6390(soc_type))) { > event_type = 0; > rlen = sizeof(*edl); > rtype = EDL_PATCH_TLV_REQ_CMD; > @@ -297,7 +304,7 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, > err = -EIO; > } > > - if (soc_type == QCA_WCN3991) > + if ((QCA_IS_3991_6390(soc_type))) > goto out; > > tlv_resp = (struct tlv_seg_resp *)(edl->data); > @@ -354,7 +361,7 @@ static int qca_download_firmware(struct hci_dev *hdev, > return ret; > } > > - qca_tlv_check_data(config, fw); > + qca_tlv_check_data(config, fw, soc_type); > > segment = fw->data; > remain = fw->size; > @@ -438,6 +445,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, > (soc_ver & 0x0000000f); > snprintf(config.fwname, sizeof(config.fwname), > "qca/crbtfw%02x.tlv", rom_ver); > + } else if (soc_type == QCA_QCA6390) { > + rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | > + (soc_ver & 0x0000000f); > + snprintf(config.fwname, sizeof(config.fwname), > + "qca/htbtfw%02x.tlv", rom_ver); > + > } else { > snprintf(config.fwname, sizeof(config.fwname), > "qca/rampatch_%08x.bin", soc_ver); > @@ -460,6 +473,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, > else if (qca_is_wcn399x(soc_type)) > snprintf(config.fwname, sizeof(config.fwname), > "qca/crnv%02x.bin", rom_ver); > + else if (soc_type == QCA_QCA6390) > + snprintf(config.fwname, sizeof(config.fwname), > + "qca/htnv%02x.bin", rom_ver); > else > snprintf(config.fwname, sizeof(config.fwname), > "qca/nvm_%08x.bin", soc_ver); > diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h > index f5795b1a3779..2f06ed7e1c50 100644 > --- a/drivers/bluetooth/btqca.h > +++ b/drivers/bluetooth/btqca.h > @@ -127,6 +127,7 @@ enum qca_btsoc_type { > QCA_WCN3990, > QCA_WCN3991, > QCA_WCN3998, > + QCA_QCA6390, > }; > > #if IS_ENABLED(CONFIG_BT_QCA) > diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c > index f10bdf8e1fc5..472f468145e8 100644 > --- a/drivers/bluetooth/hci_qca.c > +++ b/drivers/bluetooth/hci_qca.c > @@ -25,6 +25,7 @@ > #include <linux/mod_devicetable.h> > #include <linux/module.h> > #include <linux/of_device.h> > +#include <linux/acpi.h> > #include <linux/platform_device.h> > #include <linux/regulator/consumer.h> > #include <linux/serdev.h> > @@ -1355,6 +1356,16 @@ static const struct hci_uart_proto qca_proto = { > .dequeue = qca_dequeue, > }; > > +static const struct qca_vreg_data qca_soc_data_qca6174 = { > + .soc_type = QCA_ROME, > + .num_vregs = 0, > +}; > + > +static const struct qca_vreg_data qca_soc_data_qca6390 = { > + .soc_type = QCA_QCA6390, > + .num_vregs = 0, > +}; > + > static const struct qca_vreg_data qca_soc_data_wcn3990 = { > .soc_type = QCA_WCN3990, > .vregs = (struct qca_vreg []) { > @@ -1501,7 +1512,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) > return -ENOMEM; > > qcadev->serdev_hu.serdev = serdev; > - data = of_device_get_match_data(&serdev->dev); > + data = device_get_match_data(&serdev->dev); I would address this in a separate patch since it seems you are actually fixing QCA6174 support as well. Or is this because the new platform is ACPI based. I can’t tell since you are missing a proper commit message. > serdev_device_set_drvdata(serdev, qcadev); > device_property_read_string(&serdev->dev, "firmware-name", > &qcadev->firmware_name); > @@ -1534,7 +1545,10 @@ static int qca_serdev_probe(struct serdev_device *serdev) > goto out; > } > } else { > - qcadev->btsoc_type = QCA_ROME; > + if (data) > + qcadev->btsoc_type = data->soc_type; > + else > + qcadev->btsoc_type = QCA_ROME; > qcadev->bt_en = devm_gpiod_get(&serdev->dev, "enable", > GPIOD_OUT_LOW); > if (IS_ERR(qcadev->bt_en)) { > @@ -1670,21 +1684,41 @@ static int __maybe_unused qca_resume(struct device *dev) > > static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume); > > +#ifdef CONFIG_OF > static const struct of_device_id qca_bluetooth_of_match[] = { > - { .compatible = "qcom,qca6174-bt" }, > + { .compatible = "qcom,qca6174-bt" .data = &qca_soc_data_qca6174}, So this should be clearly a separate patch as mentioned above. > + { .compatible = "qcom,qca6390-bt" .data = &qca_soc_data_qca6390}, > { .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990}, > { .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991}, > { .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998}, > { /* sentinel */ } > }; > MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); > +#endif > + > +#ifdef CONFIG_ACPI > +static const struct acpi_device_id qca_bluetooth_acpi_match[] = { > + { "QCOM6390", (kernel_ulong_t)&qca_soc_data_qca6390 }, > + { "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, > + { "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, > + { "DLB26390", (kernel_ulong_t)&qca_soc_data_qca6390 }, > + { }, > +}; > +MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match); > +#endif > + > > static struct serdev_device_driver qca_serdev_driver = { > .probe = qca_serdev_probe, > .remove = qca_serdev_remove, > .driver = { > .name = "hci_uart_qca", > + #ifdef CONFIG_OF > .of_match_table = qca_bluetooth_of_match, > + #endif > + #ifdef CONFIG_ACPI > + .acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match), > + #endif These ifdefs are not needed. The ACPI_PTR does this automatically and there is another macro for OF as well that you can use. > .pm = &qca_pm_ops, > }, > }; Where is the patch addressing Kconfig dependency? If you support ACPI and DT platforms now, you need that. Regards Marcel ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 1/2] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390 2019-12-12 10:32 ` [PATCH v1 1/2] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390 Marcel Holtmann @ 2019-12-13 3:33 ` rjliao [not found] ` <471977a5037f06093945c5e71c78e538@codeaurora.org> 0 siblings, 1 reply; 8+ messages in thread From: rjliao @ 2019-12-13 3:33 UTC (permalink / raw) To: Marcel Holtmann Cc: Johan Hedberg, lkml, linux-bluetooth, linux-bluetooth-owner 在 2019-12-12 18:32,Marcel Holtmann 写道: > Hi Rocky, > >> This patch add support for QCA6390. > > can we please be a bit more descriptive on what support we are adding. > >> >> Signed-off-by: Rocky Liao <rjliao@codeaurora.org> >> --- >> drivers/bluetooth/btqca.c | 32 +++++++++++++++++++++-------- >> drivers/bluetooth/btqca.h | 1 + >> drivers/bluetooth/hci_qca.c | 40 ++++++++++++++++++++++++++++++++++--- >> 3 files changed, 62 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c >> index ec69e5dd7bd3..75990223e5e3 100644 >> --- a/drivers/bluetooth/btqca.c >> +++ b/drivers/bluetooth/btqca.c >> @@ -13,6 +13,8 @@ >> #include "btqca.h" >> >> #define VERSION "0.1" > > Lets put an extra empty line here. OK > >> +#define QCA_IS_3991_6390(soc_type) \ >> + ((soc_type == QCA_WCN3991) || (soc_type == QCA_QCA6390)) > > Actually (a == b || c == d) is enough. > > I rather do ((a) == b || (c) == d) to ensure the parameter is properly > protected. It is not needed in this case since the usage is simple. OK > >> >> int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, >> enum qca_btsoc_type soc_type) >> @@ -32,7 +34,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 >> *soc_version, >> * VSE event. WCN3991 sends version command response as a payload to >> * command complete event. >> */ >> - if (soc_type == QCA_WCN3991) { >> + if (QCA_IS_3991_6390(soc_type)) { >> event_type = 0; >> rlen += 1; >> rtype = EDL_PATCH_VER_REQ_CMD; >> @@ -69,7 +71,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 >> *soc_version, >> goto out; >> } >> >> - if (soc_type == QCA_WCN3991) >> + if ((QCA_IS_3991_6390(soc_type))) >> memmove(&edl->data, &edl->data[1], sizeof(*ver)); > > Maybe these should just be turned into a switch statement and not > using some macro. > Prefer to use macro or a simple function call, there are many places called this and use switch will make code complex >> >> ver = (struct qca_btsoc_version *)(edl->data); >> @@ -139,7 +141,7 @@ int qca_send_pre_shutdown_cmd(struct hci_dev >> *hdev) >> EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); >> >> static void qca_tlv_check_data(struct qca_fw_config *config, >> - const struct firmware *fw) >> + const struct firmware *fw, enum qca_btsoc_type soc_type) >> { >> const u8 *data; >> u32 type_len; >> @@ -148,6 +150,7 @@ static void qca_tlv_check_data(struct >> qca_fw_config *config, >> struct tlv_type_hdr *tlv; >> struct tlv_type_patch *tlv_patch; >> struct tlv_type_nvm *tlv_nvm; >> + uint8_t nvm_baud_rate = config->user_baud_rate; >> >> tlv = (struct tlv_type_hdr *)fw->data; >> >> @@ -213,10 +216,14 @@ static void qca_tlv_check_data(struct >> qca_fw_config *config, >> * enabling software inband sleep >> * onto controller side. >> */ >> - tlv_nvm->data[0] |= 0x80; >> + if (!QCA_IS_3991_6390(soc_type)) >> + tlv_nvm->data[0] |= 0x80; >> >> /* UART Baud Rate */ >> - tlv_nvm->data[2] = config->user_baud_rate; >> + if ((QCA_IS_3991_6390(soc_type))) >> + tlv_nvm->data[1] = nvm_baud_rate; >> + else >> + tlv_nvm->data[2] = nvm_baud_rate; > > These two changes are not related to the QCA6390 support. Leave them > out and if changes are needed to fix other hardware, then send them as > separate patch. > OK >> >> break; >> >> @@ -264,7 +271,7 @@ static int qca_tlv_send_segment(struct hci_dev >> *hdev, int seg_size, >> * VSE event. WCN3991 sends version command response as a payload to >> * command complete event. >> */ >> - if (soc_type == QCA_WCN3991) { >> + if ((QCA_IS_3991_6390(soc_type))) { >> event_type = 0; >> rlen = sizeof(*edl); >> rtype = EDL_PATCH_TLV_REQ_CMD; >> @@ -297,7 +304,7 @@ static int qca_tlv_send_segment(struct hci_dev >> *hdev, int seg_size, >> err = -EIO; >> } >> >> - if (soc_type == QCA_WCN3991) >> + if ((QCA_IS_3991_6390(soc_type))) >> goto out; >> >> tlv_resp = (struct tlv_seg_resp *)(edl->data); >> @@ -354,7 +361,7 @@ static int qca_download_firmware(struct hci_dev >> *hdev, >> return ret; >> } >> >> - qca_tlv_check_data(config, fw); >> + qca_tlv_check_data(config, fw, soc_type); >> >> segment = fw->data; >> remain = fw->size; >> @@ -438,6 +445,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t >> baudrate, >> (soc_ver & 0x0000000f); >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/crbtfw%02x.tlv", rom_ver); >> + } else if (soc_type == QCA_QCA6390) { >> + rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | >> + (soc_ver & 0x0000000f); >> + snprintf(config.fwname, sizeof(config.fwname), >> + "qca/htbtfw%02x.tlv", rom_ver); >> + >> } else { >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/rampatch_%08x.bin", soc_ver); >> @@ -460,6 +473,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t >> baudrate, >> else if (qca_is_wcn399x(soc_type)) >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/crnv%02x.bin", rom_ver); >> + else if (soc_type == QCA_QCA6390) >> + snprintf(config.fwname, sizeof(config.fwname), >> + "qca/htnv%02x.bin", rom_ver); >> else >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/nvm_%08x.bin", soc_ver); >> diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h >> index f5795b1a3779..2f06ed7e1c50 100644 >> --- a/drivers/bluetooth/btqca.h >> +++ b/drivers/bluetooth/btqca.h >> @@ -127,6 +127,7 @@ enum qca_btsoc_type { >> QCA_WCN3990, >> QCA_WCN3991, >> QCA_WCN3998, >> + QCA_QCA6390, >> }; >> >> #if IS_ENABLED(CONFIG_BT_QCA) >> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c >> index f10bdf8e1fc5..472f468145e8 100644 >> --- a/drivers/bluetooth/hci_qca.c >> +++ b/drivers/bluetooth/hci_qca.c >> @@ -25,6 +25,7 @@ >> #include <linux/mod_devicetable.h> >> #include <linux/module.h> >> #include <linux/of_device.h> >> +#include <linux/acpi.h> >> #include <linux/platform_device.h> >> #include <linux/regulator/consumer.h> >> #include <linux/serdev.h> >> @@ -1355,6 +1356,16 @@ static const struct hci_uart_proto qca_proto = >> { >> .dequeue = qca_dequeue, >> }; >> >> +static const struct qca_vreg_data qca_soc_data_qca6174 = { >> + .soc_type = QCA_ROME, >> + .num_vregs = 0, >> +}; >> + >> +static const struct qca_vreg_data qca_soc_data_qca6390 = { >> + .soc_type = QCA_QCA6390, >> + .num_vregs = 0, >> +}; >> + >> static const struct qca_vreg_data qca_soc_data_wcn3990 = { >> .soc_type = QCA_WCN3990, >> .vregs = (struct qca_vreg []) { >> @@ -1501,7 +1512,7 @@ static int qca_serdev_probe(struct serdev_device >> *serdev) >> return -ENOMEM; >> >> qcadev->serdev_hu.serdev = serdev; >> - data = of_device_get_match_data(&serdev->dev); >> + data = device_get_match_data(&serdev->dev); > > I would address this in a separate patch since it seems you are > actually fixing QCA6174 support as well. Or is this because the new > platform is ACPI based. I can’t tell since you are missing a proper > commit message. > OK >> serdev_device_set_drvdata(serdev, qcadev); >> device_property_read_string(&serdev->dev, "firmware-name", >> &qcadev->firmware_name); >> @@ -1534,7 +1545,10 @@ static int qca_serdev_probe(struct >> serdev_device *serdev) >> goto out; >> } >> } else { >> - qcadev->btsoc_type = QCA_ROME; >> + if (data) >> + qcadev->btsoc_type = data->soc_type; >> + else >> + qcadev->btsoc_type = QCA_ROME; >> qcadev->bt_en = devm_gpiod_get(&serdev->dev, "enable", >> GPIOD_OUT_LOW); >> if (IS_ERR(qcadev->bt_en)) { >> @@ -1670,21 +1684,41 @@ static int __maybe_unused qca_resume(struct >> device *dev) >> >> static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume); >> >> +#ifdef CONFIG_OF >> static const struct of_device_id qca_bluetooth_of_match[] = { >> - { .compatible = "qcom,qca6174-bt" }, >> + { .compatible = "qcom,qca6174-bt" .data = &qca_soc_data_qca6174}, > > So this should be clearly a separate patch as mentioned above. > OK >> + { .compatible = "qcom,qca6390-bt" .data = &qca_soc_data_qca6390}, >> { .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990}, >> { .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991}, >> { .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998}, >> { /* sentinel */ } >> }; >> MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); >> +#endif >> + >> +#ifdef CONFIG_ACPI >> +static const struct acpi_device_id qca_bluetooth_acpi_match[] = { >> + { "QCOM6390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >> + { "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >> + { "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >> + { "DLB26390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >> + { }, >> +}; >> +MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match); >> +#endif >> + >> >> static struct serdev_device_driver qca_serdev_driver = { >> .probe = qca_serdev_probe, >> .remove = qca_serdev_remove, >> .driver = { >> .name = "hci_uart_qca", >> + #ifdef CONFIG_OF >> .of_match_table = qca_bluetooth_of_match, >> + #endif >> + #ifdef CONFIG_ACPI >> + .acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match), >> + #endif > > These ifdefs are not needed. The ACPI_PTR does this automatically and > there is another macro for OF as well that you can use. > OK >> .pm = &qca_pm_ops, >> }, >> }; > > Where is the patch addressing Kconfig dependency? If you support ACPI > and DT platforms now, you need that. > OK > Regards > > Marcel ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <471977a5037f06093945c5e71c78e538@codeaurora.org>]
* Re: [PATCH v1 1/2] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390 [not found] ` <471977a5037f06093945c5e71c78e538@codeaurora.org> @ 2019-12-13 7:41 ` Marcel Holtmann 0 siblings, 0 replies; 8+ messages in thread From: Marcel Holtmann @ 2019-12-13 7:41 UTC (permalink / raw) To: Rocky Liao; +Cc: Johan Hedberg, lkml, linux-bluetooth, linux-bluetooth-owner Hi Rocky, >>>> This patch add support for QCA6390. >>> >>> can we please be a bit more descriptive on what support we are adding. >>> >>>> >>>> Signed-off-by: Rocky Liao <rjliao@codeaurora.org> >>>> --- >>>> drivers/bluetooth/btqca.c | 32 +++++++++++++++++++++-------- >>>> drivers/bluetooth/btqca.h | 1 + >>>> drivers/bluetooth/hci_qca.c | 40 ++++++++++++++++++++++++++++++++++--- >>>> 3 files changed, 62 insertions(+), 11 deletions(-) >>>> >>>> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c >>>> index ec69e5dd7bd3..75990223e5e3 100644 >>>> --- a/drivers/bluetooth/btqca.c >>>> +++ b/drivers/bluetooth/btqca.c >>>> @@ -13,6 +13,8 @@ >>>> #include "btqca.h" >>>> >>>> #define VERSION "0.1" >>> >>> Lets put an extra empty line here. >> OK >> >>> >>>> +#define QCA_IS_3991_6390(soc_type) \ >>>> + ((soc_type == QCA_WCN3991) || (soc_type == QCA_QCA6390)) >>> >>> Actually (a == b || c == d) is enough. >>> >>> I rather do ((a) == b || (c) == d) to ensure the parameter is properly >>> protected. It is not needed in this case since the usage is simple. >> OK >> >>> >>>> >>>> int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, >>>> enum qca_btsoc_type soc_type) >>>> @@ -32,7 +34,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, >>>> * VSE event. WCN3991 sends version command response as a payload to >>>> * command complete event. >>>> */ >>>> - if (soc_type == QCA_WCN3991) { >>>> + if (QCA_IS_3991_6390(soc_type)) { >>>> event_type = 0; >>>> rlen += 1; >>>> rtype = EDL_PATCH_VER_REQ_CMD; >>>> @@ -69,7 +71,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, >>>> goto out; >>>> } >>>> >>>> - if (soc_type == QCA_WCN3991) >>>> + if ((QCA_IS_3991_6390(soc_type))) >>>> memmove(&edl->data, &edl->data[1], sizeof(*ver)); >>> >>> Maybe these should just be turned into a switch statement and not >>> using some macro. >> Prefer to use macro or a simple function call, there are many places >> called this and use switch will make code complex >> >>>> >>>> ver = (struct qca_btsoc_version *)(edl->data); >>>> @@ -139,7 +141,7 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) >>>> EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); >>>> >>>> static void qca_tlv_check_data(struct qca_fw_config *config, >>>> - const struct firmware *fw) >>>> + const struct firmware *fw, enum qca_btsoc_type soc_type) >>>> { >>>> const u8 *data; >>>> u32 type_len; >>>> @@ -148,6 +150,7 @@ static void qca_tlv_check_data(struct qca_fw_config *config, >>>> struct tlv_type_hdr *tlv; >>>> struct tlv_type_patch *tlv_patch; >>>> struct tlv_type_nvm *tlv_nvm; >>>> + uint8_t nvm_baud_rate = config->user_baud_rate; >>>> >>>> tlv = (struct tlv_type_hdr *)fw->data; >>>> >>>> @@ -213,10 +216,14 @@ static void qca_tlv_check_data(struct qca_fw_config *config, >>>> * enabling software inband sleep >>>> * onto controller side. >>>> */ >>>> - tlv_nvm->data[0] |= 0x80; >>>> + if (!QCA_IS_3991_6390(soc_type)) >>>> + tlv_nvm->data[0] |= 0x80; >>>> >>>> /* UART Baud Rate */ >>>> - tlv_nvm->data[2] = config->user_baud_rate; >>>> + if ((QCA_IS_3991_6390(soc_type))) >>>> + tlv_nvm->data[1] = nvm_baud_rate; >>>> + else >>>> + tlv_nvm->data[2] = nvm_baud_rate; >>> >>> These two changes are not related to the QCA6390 support. Leave them >>> out and if changes are needed to fix other hardware, then send them as >>> separate patch. >> OK >> >>>> >>>> break; >>>> >>>> @@ -264,7 +271,7 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, >>>> * VSE event. WCN3991 sends version command response as a payload to >>>> * command complete event. >>>> */ >>>> - if (soc_type == QCA_WCN3991) { >>>> + if ((QCA_IS_3991_6390(soc_type))) { >>>> event_type = 0; >>>> rlen = sizeof(*edl); >>>> rtype = EDL_PATCH_TLV_REQ_CMD; >>>> @@ -297,7 +304,7 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, >>>> err = -EIO; >>>> } >>>> >>>> - if (soc_type == QCA_WCN3991) >>>> + if ((QCA_IS_3991_6390(soc_type))) >>>> goto out; >>>> >>>> tlv_resp = (struct tlv_seg_resp *)(edl->data); >>>> @@ -354,7 +361,7 @@ static int qca_download_firmware(struct hci_dev *hdev, >>>> return ret; >>>> } >>>> >>>> - qca_tlv_check_data(config, fw); >>>> + qca_tlv_check_data(config, fw, soc_type); >>>> >>>> segment = fw->data; >>>> remain = fw->size; >>>> @@ -438,6 +445,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, >>>> (soc_ver & 0x0000000f); >>>> snprintf(config.fwname, sizeof(config.fwname), >>>> "qca/crbtfw%02x.tlv", rom_ver); >>>> + } else if (soc_type == QCA_QCA6390) { >>>> + rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | >>>> + (soc_ver & 0x0000000f); >>>> + snprintf(config.fwname, sizeof(config.fwname), >>>> + "qca/htbtfw%02x.tlv", rom_ver); >>>> + >>>> } else { >>>> snprintf(config.fwname, sizeof(config.fwname), >>>> "qca/rampatch_%08x.bin", soc_ver); >>>> @@ -460,6 +473,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, >>>> else if (qca_is_wcn399x(soc_type)) >>>> snprintf(config.fwname, sizeof(config.fwname), >>>> "qca/crnv%02x.bin", rom_ver); >>>> + else if (soc_type == QCA_QCA6390) >>>> + snprintf(config.fwname, sizeof(config.fwname), >>>> + "qca/htnv%02x.bin", rom_ver); >>>> else >>>> snprintf(config.fwname, sizeof(config.fwname), >>>> "qca/nvm_%08x.bin", soc_ver); >>>> diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h >>>> index f5795b1a3779..2f06ed7e1c50 100644 >>>> --- a/drivers/bluetooth/btqca.h >>>> +++ b/drivers/bluetooth/btqca.h >>>> @@ -127,6 +127,7 @@ enum qca_btsoc_type { >>>> QCA_WCN3990, >>>> QCA_WCN3991, >>>> QCA_WCN3998, >>>> + QCA_QCA6390, >>>> }; >>>> >>>> #if IS_ENABLED(CONFIG_BT_QCA) >>>> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c >>>> index f10bdf8e1fc5..472f468145e8 100644 >>>> --- a/drivers/bluetooth/hci_qca.c >>>> +++ b/drivers/bluetooth/hci_qca.c >>>> @@ -25,6 +25,7 @@ >>>> #include <linux/mod_devicetable.h> >>>> #include <linux/module.h> >>>> #include <linux/of_device.h> >>>> +#include <linux/acpi.h> >>>> #include <linux/platform_device.h> >>>> #include <linux/regulator/consumer.h> >>>> #include <linux/serdev.h> >>>> @@ -1355,6 +1356,16 @@ static const struct hci_uart_proto qca_proto = { >>>> .dequeue = qca_dequeue, >>>> }; >>>> >>>> +static const struct qca_vreg_data qca_soc_data_qca6174 = { >>>> + .soc_type = QCA_ROME, >>>> + .num_vregs = 0, >>>> +}; >>>> + >>>> +static const struct qca_vreg_data qca_soc_data_qca6390 = { >>>> + .soc_type = QCA_QCA6390, >>>> + .num_vregs = 0, >>>> +}; >>>> + >>>> static const struct qca_vreg_data qca_soc_data_wcn3990 = { >>>> .soc_type = QCA_WCN3990, >>>> .vregs = (struct qca_vreg []) { >>>> @@ -1501,7 +1512,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) >>>> return -ENOMEM; >>>> >>>> qcadev->serdev_hu.serdev = serdev; >>>> - data = of_device_get_match_data(&serdev->dev); >>>> + data = device_get_match_data(&serdev->dev); >>> >>> I would address this in a separate patch since it seems you are >>> actually fixing QCA6174 support as well. Or is this because the new >>> platform is ACPI based. I can’t tell since you are missing a proper >>> commit message. >> OK >>>> serdev_device_set_drvdata(serdev, qcadev); >>>> device_property_read_string(&serdev->dev, "firmware-name", >>>> &qcadev->firmware_name); >>>> @@ -1534,7 +1545,10 @@ static int qca_serdev_probe(struct serdev_device *serdev) >>>> goto out; >>>> } >>>> } else { >>>> - qcadev->btsoc_type = QCA_ROME; >>>> + if (data) >>>> + qcadev->btsoc_type = data->soc_type; >>>> + else >>>> + qcadev->btsoc_type = QCA_ROME; >>>> qcadev->bt_en = devm_gpiod_get(&serdev->dev, "enable", >>>> GPIOD_OUT_LOW); >>>> if (IS_ERR(qcadev->bt_en)) { >>>> @@ -1670,21 +1684,41 @@ static int __maybe_unused qca_resume(struct device *dev) >>>> >>>> static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume); >>>> >>>> +#ifdef CONFIG_OF >>>> static const struct of_device_id qca_bluetooth_of_match[] = { >>>> - { .compatible = "qcom,qca6174-bt" }, >>>> + { .compatible = "qcom,qca6174-bt" .data = &qca_soc_data_qca6174}, >>> >>> So this should be clearly a separate patch as mentioned above. >> OK >>>> + { .compatible = "qcom,qca6390-bt" .data = &qca_soc_data_qca6390}, >>>> { .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990}, >>>> { .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991}, >>>> { .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998}, >>>> { /* sentinel */ } >>>> }; >>>> MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); >>>> +#endif >>>> + >>>> +#ifdef CONFIG_ACPI >>>> +static const struct acpi_device_id qca_bluetooth_acpi_match[] = { >>>> + { "QCOM6390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >>>> + { "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >>>> + { "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >>>> + { "DLB26390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >>>> + { }, >>>> +}; >>>> +MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match); >>>> +#endif >>>> + >>>> >>>> static struct serdev_device_driver qca_serdev_driver = { >>>> .probe = qca_serdev_probe, >>>> .remove = qca_serdev_remove, >>>> .driver = { >>>> .name = "hci_uart_qca", >>>> + #ifdef CONFIG_OF >>>> .of_match_table = qca_bluetooth_of_match, >>>> + #endif >>>> + #ifdef CONFIG_ACPI >>>> + .acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match), >>>> + #endif >>> >>> These ifdefs are not needed. The ACPI_PTR does this automatically and >>> there is another macro for OF as well that you can use. >> OK >>>> .pm = &qca_pm_ops, >>>> }, >>>> }; >>> >>> Where is the patch addressing Kconfig dependency? If you support ACPI >>> and DT platforms now, you need that. >> OK > I am a bit confusing what kind of Kconfig change is required,the driver shoud > be able to work no matter it's ACPI or DT platform. We should have no > dependency on ACPI or DT, right? can this driver work without ACPI or DT? The other drivers have some dependency on ACPI or DT. Regards Marcel ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <20200314094328.3331-1-rjliao@codeaurora.org>]
* Re: [PATCH v1 1/2] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390 [not found] <20200314094328.3331-1-rjliao@codeaurora.org> @ 2020-03-16 15:04 ` bgodavar 2020-03-23 9:12 ` Rocky Liao 2020-03-16 17:46 ` Matthias Kaehlcke 1 sibling, 1 reply; 8+ messages in thread From: bgodavar @ 2020-03-16 15:04 UTC (permalink / raw) To: Rocky Liao Cc: marcel, johan.hedberg, linux-kernel, linux-bluetooth, linux-arm-msm, c-hbandi, hemantg, mka On 2020-03-14 15:13, Rocky Liao wrote: > This patch adds support for QCA6390, including the devicetree and acpi > compatible hwid matching, and patch/nvm downloading. > > Signed-off-by: Rocky Liao <rjliao@codeaurora.org> > --- > drivers/bluetooth/btqca.c | 44 +++++++++++++++++++++++++++++++---- > drivers/bluetooth/btqca.h | 8 +++++++ > drivers/bluetooth/hci_qca.c | 46 +++++++++++++++++++++++++++++++------ > 3 files changed, 86 insertions(+), 12 deletions(-) > > diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c > index a16845c0751d..ca126e499c58 100644 > --- a/drivers/bluetooth/btqca.c > +++ b/drivers/bluetooth/btqca.c > @@ -14,6 +14,9 @@ > > #define VERSION "0.1" > > +#define QCA_IS_3991_6390(soc_type) \ > + (soc_type == QCA_WCN3991 || soc_type == QCA_QCA6390) > + [Bala]: Why don't we do >= QCA_WCN3991 (mostly both the devices support same features) > int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, > enum qca_btsoc_type soc_type) > { > @@ -32,7 +35,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 > *soc_version, > * VSE event. WCN3991 sends version command response as a payload to > * command complete event. > */ > - if (soc_type == QCA_WCN3991) { > + if (QCA_IS_3991_6390(soc_type)) { > event_type = 0; > rlen += 1; > rtype = EDL_PATCH_VER_REQ_CMD; > @@ -69,7 +72,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 > *soc_version, > goto out; > } > > - if (soc_type == QCA_WCN3991) > + if (QCA_IS_3991_6390(soc_type)) > memmove(&edl->data, &edl->data[1], sizeof(*ver)); > > ver = (struct qca_btsoc_version *)(edl->data); > @@ -138,6 +141,29 @@ int qca_send_pre_shutdown_cmd(struct hci_dev > *hdev) > } > EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); > > +int qca_send_enhancelog_enable_cmd(struct hci_dev *hdev) > +{ > + struct sk_buff *skb; > + int err; > + const u8 param[2] = {0x14, 0x01}; [Bala]: advisable to use MACRO's > + > + bt_dev_dbg(hdev, "QCA enhanced log enable cmd"); > + > + skb = __hci_cmd_sync_ev(hdev, QCA_ENHANCED_LOG_ENABLE_CMD, 2, > + param, HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT); > + > + if (IS_ERR(skb)) { > + err = PTR_ERR(skb); > + bt_dev_err(hdev, "Enhanced log enable cmd failed (%d)", err); > + return err; > + } > + > + kfree_skb(skb); > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(qca_send_enhancelog_enable_cmd); > + > static void qca_tlv_check_data(struct qca_fw_config *config, > const struct firmware *fw, enum qca_btsoc_type soc_type) > { > @@ -217,7 +243,7 @@ static void qca_tlv_check_data(struct qca_fw_config > *config, > tlv_nvm->data[0] |= 0x80; > > /* UART Baud Rate */ > - if (soc_type == QCA_WCN3991) > + if (QCA_IS_3991_6390(soc_type)) > tlv_nvm->data[1] = nvm_baud_rate; > else > tlv_nvm->data[2] = nvm_baud_rate; > @@ -268,7 +294,7 @@ static int qca_tlv_send_segment(struct hci_dev > *hdev, int seg_size, > * VSE event. WCN3991 sends version command response as a payload to > * command complete event. > */ > - if (soc_type == QCA_WCN3991) { > + if (QCA_IS_3991_6390(soc_type)) { > event_type = 0; > rlen = sizeof(*edl); > rtype = EDL_PATCH_TLV_REQ_CMD; > @@ -301,7 +327,7 @@ static int qca_tlv_send_segment(struct hci_dev > *hdev, int seg_size, > err = -EIO; > } > > - if (soc_type == QCA_WCN3991) > + if (QCA_IS_3991_6390(soc_type)) > goto out; > > tlv_resp = (struct tlv_seg_resp *)(edl->data); > @@ -442,6 +468,11 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t > baudrate, > (soc_ver & 0x0000000f); > snprintf(config.fwname, sizeof(config.fwname), > "qca/crbtfw%02x.tlv", rom_ver); > + } else if (soc_type == QCA_QCA6390) { > + rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | > + (soc_ver & 0x0000000f); > + snprintf(config.fwname, sizeof(config.fwname), > + "qca/htbtfw%02x.tlv", rom_ver); [Bala]: This part we need to rethink to having to optimize. ROME use: rampatch<>.tlv WCN399x: uses cr<>.tlv QCA6390: uses ht tomorrow if some new chipset comes, it uses different name again a we need to handle this part. i would suggest add this prefix to "qca_bluetooth_of_match" which can be passed as argument > } else { > snprintf(config.fwname, sizeof(config.fwname), > "qca/rampatch_%08x.bin", soc_ver); > @@ -464,6 +495,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t > baudrate, > else if (qca_is_wcn399x(soc_type)) > snprintf(config.fwname, sizeof(config.fwname), > "qca/crnv%02x.bin", rom_ver); > + else if (soc_type == QCA_QCA6390) > + snprintf(config.fwname, sizeof(config.fwname), > + "qca/htnv%02x.bin", rom_ver); > else > snprintf(config.fwname, sizeof(config.fwname), > "qca/nvm_%08x.bin", soc_ver); > diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h > index e16a4d650597..bc703817c3d7 100644 > --- a/drivers/bluetooth/btqca.h > +++ b/drivers/bluetooth/btqca.h > @@ -14,6 +14,7 @@ > #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) > #define MAX_SIZE_PER_TLV_SEGMENT (243) > #define QCA_PRE_SHUTDOWN_CMD (0xFC08) > +#define QCA_ENHANCED_LOG_ENABLE_CMD (0xFC17) > > #define EDL_CMD_REQ_RES_EVT (0x00) > #define EDL_PATCH_VER_RES_EVT (0x19) > @@ -127,6 +128,7 @@ enum qca_btsoc_type { > QCA_WCN3990, > QCA_WCN3991, > QCA_WCN3998, > + QCA_QCA6390, > }; > > #if IS_ENABLED(CONFIG_BT_QCA) > @@ -139,6 +141,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 > *soc_version, > enum qca_btsoc_type); > int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); > int qca_send_pre_shutdown_cmd(struct hci_dev *hdev); > +int qca_send_enhancelog_enable_cmd(struct hci_dev *hdev); > static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) > { > return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3991 || > @@ -178,4 +181,9 @@ static inline int qca_send_pre_shutdown_cmd(struct > hci_dev *hdev) > { > return -EOPNOTSUPP; > } > + > +static inline int qca_send_enhancelog_enable_cmd(struct hci_dev *hdev) > +{ > + return -EOPNOTSUPP; > +} > #endif > diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c > index 439392b1c043..0176264b0828 100644 > --- a/drivers/bluetooth/hci_qca.c > +++ b/drivers/bluetooth/hci_qca.c > @@ -26,6 +26,7 @@ > #include <linux/mod_devicetable.h> > #include <linux/module.h> > #include <linux/of_device.h> > +#include <linux/acpi.h> > #include <linux/platform_device.h> > #include <linux/regulator/consumer.h> > #include <linux/serdev.h> > @@ -1596,7 +1597,7 @@ static int qca_setup(struct hci_uart *hu) > set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); > > bt_dev_info(hdev, "setting up %s", > - qca_is_wcn399x(soc_type) ? "wcn399x" : "ROME"); > + qca_is_wcn399x(soc_type) ? "wcn399x" : "ROME/QCA6390"); > > retry: > ret = qca_power_on(hdev); > @@ -1639,6 +1640,12 @@ static int qca_setup(struct hci_uart *hu) > qca_debugfs_init(hdev); > hu->hdev->hw_error = qca_hw_error; > hu->hdev->cmd_timeout = qca_cmd_timeout; > + > + /* QCA6390 FW doesn't enable enhanced log by default > + * need to send VSC to enable it > + */ > + if (soc_type == QCA_QCA6390) > + qca_send_enhancelog_enable_cmd(hdev); > } else if (ret == -ENOENT) { > /* No patch/nvm-config found, run with original fw/config */ > ret = 0; > @@ -1665,10 +1672,10 @@ static int qca_setup(struct hci_uart *hu) > } > > /* Setup bdaddr */ > - if (qca_is_wcn399x(soc_type)) > - hu->hdev->set_bdaddr = qca_set_bdaddr; > - else > + if (soc_type == QCA_ROME) > hu->hdev->set_bdaddr = qca_set_bdaddr_rome; > + else > + hu->hdev->set_bdaddr = qca_set_bdaddr; > > return ret; > } > @@ -1721,6 +1728,11 @@ static const struct qca_vreg_data > qca_soc_data_wcn3998 = { > .num_vregs = 4, > }; > > +static const struct qca_vreg_data qca_soc_data_qca6390 = { > + .soc_type = QCA_QCA6390, > + .num_vregs = 0, > +}; > + > static void qca_power_shutdown(struct hci_uart *hu) > { > struct qca_serdev *qcadev; > @@ -1764,7 +1776,7 @@ static int qca_power_off(struct hci_dev *hdev) > enum qca_btsoc_type soc_type = qca_soc_type(hu); > > /* Stop sending shutdown command if soc crashes. */ > - if (qca_is_wcn399x(soc_type) > + if (soc_type != QCA_ROME > && qca->memdump_state == QCA_MEMDUMP_IDLE) { > qca_send_pre_shutdown_cmd(hdev); > usleep_range(8000, 10000); > @@ -1900,7 +1912,11 @@ static int qca_serdev_probe(struct serdev_device > *serdev) > return err; > } > } else { > - qcadev->btsoc_type = QCA_ROME; > + if (data) > + qcadev->btsoc_type = data->soc_type; > + else > + qcadev->btsoc_type = QCA_ROME; > + > qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", > GPIOD_OUT_LOW); > if (!qcadev->bt_en) { > @@ -2044,21 +2060,37 @@ static int __maybe_unused qca_resume(struct > device *dev) > > static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume); > > +#ifdef CONFIG_OF > static const struct of_device_id qca_bluetooth_of_match[] = { > { .compatible = "qcom,qca6174-bt" }, > + { .compatible = "qcom,qca6390-bt", .data = &qca_soc_data_qca6390}, > { .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990}, > { .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991}, > { .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998}, > { /* sentinel */ } > }; > MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); > +#endif > + > +#ifdef CONFIG_ACPI > +static const struct acpi_device_id qca_bluetooth_acpi_match[] = { > + { "QCOM6390", (kernel_ulong_t)&qca_soc_data_qca6390 }, > + { "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, > + { "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, > + { "DLB26390", (kernel_ulong_t)&qca_soc_data_qca6390 }, > + { }, > +}; > +MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match); > +#endif > + > > static struct serdev_device_driver qca_serdev_driver = { > .probe = qca_serdev_probe, > .remove = qca_serdev_remove, > .driver = { > .name = "hci_uart_qca", > - .of_match_table = qca_bluetooth_of_match, > + .of_match_table = of_match_ptr(qca_bluetooth_of_match), > + .acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match), > .pm = &qca_pm_ops, > }, > }; ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 1/2] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390 2020-03-16 15:04 ` bgodavar @ 2020-03-23 9:12 ` Rocky Liao 0 siblings, 0 replies; 8+ messages in thread From: Rocky Liao @ 2020-03-23 9:12 UTC (permalink / raw) To: bgodavar Cc: marcel, johan.hedberg, linux-kernel, linux-bluetooth, linux-arm-msm, c-hbandi, hemantg, mka 在 2020-03-16 23:04,bgodavar@codeaurora.org 写道: > On 2020-03-14 15:13, Rocky Liao wrote: >> This patch adds support for QCA6390, including the devicetree and acpi >> compatible hwid matching, and patch/nvm downloading. >> >> Signed-off-by: Rocky Liao <rjliao@codeaurora.org> >> --- >> drivers/bluetooth/btqca.c | 44 +++++++++++++++++++++++++++++++---- >> drivers/bluetooth/btqca.h | 8 +++++++ >> drivers/bluetooth/hci_qca.c | 46 >> +++++++++++++++++++++++++++++++------ >> 3 files changed, 86 insertions(+), 12 deletions(-) >> >> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c >> index a16845c0751d..ca126e499c58 100644 >> --- a/drivers/bluetooth/btqca.c >> +++ b/drivers/bluetooth/btqca.c >> @@ -14,6 +14,9 @@ >> >> #define VERSION "0.1" >> >> +#define QCA_IS_3991_6390(soc_type) \ >> + (soc_type == QCA_WCN3991 || soc_type == QCA_QCA6390) >> + > > [Bala]: Why don't we do >= QCA_WCN3991 (mostly both the devices > support same features) > OK >> int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, >> enum qca_btsoc_type soc_type) >> { >> @@ -32,7 +35,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 >> *soc_version, >> * VSE event. WCN3991 sends version command response as a payload to >> * command complete event. >> */ >> - if (soc_type == QCA_WCN3991) { >> + if (QCA_IS_3991_6390(soc_type)) { >> event_type = 0; >> rlen += 1; >> rtype = EDL_PATCH_VER_REQ_CMD; >> @@ -69,7 +72,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 >> *soc_version, >> goto out; >> } >> >> - if (soc_type == QCA_WCN3991) >> + if (QCA_IS_3991_6390(soc_type)) >> memmove(&edl->data, &edl->data[1], sizeof(*ver)); >> >> ver = (struct qca_btsoc_version *)(edl->data); >> @@ -138,6 +141,29 @@ int qca_send_pre_shutdown_cmd(struct hci_dev >> *hdev) >> } >> EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); >> >> +int qca_send_enhancelog_enable_cmd(struct hci_dev *hdev) >> +{ >> + struct sk_buff *skb; >> + int err; >> + const u8 param[2] = {0x14, 0x01}; > > [Bala]: advisable to use MACRO's > This func will be removed, we don't need to enable enhanced log by default. It can be done by hcitool whenever needed. >> + >> + bt_dev_dbg(hdev, "QCA enhanced log enable cmd"); >> + >> + skb = __hci_cmd_sync_ev(hdev, QCA_ENHANCED_LOG_ENABLE_CMD, 2, >> + param, HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT); >> + >> + if (IS_ERR(skb)) { >> + err = PTR_ERR(skb); >> + bt_dev_err(hdev, "Enhanced log enable cmd failed (%d)", err); >> + return err; >> + } >> + >> + kfree_skb(skb); >> + >> + return 0; >> +} >> +EXPORT_SYMBOL_GPL(qca_send_enhancelog_enable_cmd); >> + >> static void qca_tlv_check_data(struct qca_fw_config *config, >> const struct firmware *fw, enum qca_btsoc_type soc_type) >> { >> @@ -217,7 +243,7 @@ static void qca_tlv_check_data(struct >> qca_fw_config *config, >> tlv_nvm->data[0] |= 0x80; >> >> /* UART Baud Rate */ >> - if (soc_type == QCA_WCN3991) >> + if (QCA_IS_3991_6390(soc_type)) >> tlv_nvm->data[1] = nvm_baud_rate; >> else >> tlv_nvm->data[2] = nvm_baud_rate; >> @@ -268,7 +294,7 @@ static int qca_tlv_send_segment(struct hci_dev >> *hdev, int seg_size, >> * VSE event. WCN3991 sends version command response as a payload to >> * command complete event. >> */ >> - if (soc_type == QCA_WCN3991) { >> + if (QCA_IS_3991_6390(soc_type)) { >> event_type = 0; >> rlen = sizeof(*edl); >> rtype = EDL_PATCH_TLV_REQ_CMD; >> @@ -301,7 +327,7 @@ static int qca_tlv_send_segment(struct hci_dev >> *hdev, int seg_size, >> err = -EIO; >> } >> >> - if (soc_type == QCA_WCN3991) >> + if (QCA_IS_3991_6390(soc_type)) >> goto out; >> >> tlv_resp = (struct tlv_seg_resp *)(edl->data); >> @@ -442,6 +468,11 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t >> baudrate, >> (soc_ver & 0x0000000f); >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/crbtfw%02x.tlv", rom_ver); >> + } else if (soc_type == QCA_QCA6390) { >> + rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | >> + (soc_ver & 0x0000000f); >> + snprintf(config.fwname, sizeof(config.fwname), >> + "qca/htbtfw%02x.tlv", rom_ver); > > [Bala]: This part we need to rethink to having to optimize. > > ROME use: rampatch<>.tlv > WCN399x: uses cr<>.tlv > QCA6390: uses ht > tomorrow if some new chipset comes, it uses different name again a we > need to handle this part. > i would suggest add this prefix to "qca_bluetooth_of_match" > which can be passed as argument > I would like to do this in a separate patch. >> } else { >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/rampatch_%08x.bin", soc_ver); >> @@ -464,6 +495,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t >> baudrate, >> else if (qca_is_wcn399x(soc_type)) >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/crnv%02x.bin", rom_ver); >> + else if (soc_type == QCA_QCA6390) >> + snprintf(config.fwname, sizeof(config.fwname), >> + "qca/htnv%02x.bin", rom_ver); >> else >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/nvm_%08x.bin", soc_ver); >> diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h >> index e16a4d650597..bc703817c3d7 100644 >> --- a/drivers/bluetooth/btqca.h >> +++ b/drivers/bluetooth/btqca.h >> @@ -14,6 +14,7 @@ >> #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) >> #define MAX_SIZE_PER_TLV_SEGMENT (243) >> #define QCA_PRE_SHUTDOWN_CMD (0xFC08) >> +#define QCA_ENHANCED_LOG_ENABLE_CMD (0xFC17) >> >> #define EDL_CMD_REQ_RES_EVT (0x00) >> #define EDL_PATCH_VER_RES_EVT (0x19) >> @@ -127,6 +128,7 @@ enum qca_btsoc_type { >> QCA_WCN3990, >> QCA_WCN3991, >> QCA_WCN3998, >> + QCA_QCA6390, >> }; >> >> #if IS_ENABLED(CONFIG_BT_QCA) >> @@ -139,6 +141,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 >> *soc_version, >> enum qca_btsoc_type); >> int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); >> int qca_send_pre_shutdown_cmd(struct hci_dev *hdev); >> +int qca_send_enhancelog_enable_cmd(struct hci_dev *hdev); >> static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type) >> { >> return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3991 || >> @@ -178,4 +181,9 @@ static inline int qca_send_pre_shutdown_cmd(struct >> hci_dev *hdev) >> { >> return -EOPNOTSUPP; >> } >> + >> +static inline int qca_send_enhancelog_enable_cmd(struct hci_dev >> *hdev) >> +{ >> + return -EOPNOTSUPP; >> +} >> #endif >> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c >> index 439392b1c043..0176264b0828 100644 >> --- a/drivers/bluetooth/hci_qca.c >> +++ b/drivers/bluetooth/hci_qca.c >> @@ -26,6 +26,7 @@ >> #include <linux/mod_devicetable.h> >> #include <linux/module.h> >> #include <linux/of_device.h> >> +#include <linux/acpi.h> >> #include <linux/platform_device.h> >> #include <linux/regulator/consumer.h> >> #include <linux/serdev.h> >> @@ -1596,7 +1597,7 @@ static int qca_setup(struct hci_uart *hu) >> set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks); >> >> bt_dev_info(hdev, "setting up %s", >> - qca_is_wcn399x(soc_type) ? "wcn399x" : "ROME"); >> + qca_is_wcn399x(soc_type) ? "wcn399x" : "ROME/QCA6390"); >> >> retry: >> ret = qca_power_on(hdev); >> @@ -1639,6 +1640,12 @@ static int qca_setup(struct hci_uart *hu) >> qca_debugfs_init(hdev); >> hu->hdev->hw_error = qca_hw_error; >> hu->hdev->cmd_timeout = qca_cmd_timeout; >> + >> + /* QCA6390 FW doesn't enable enhanced log by default >> + * need to send VSC to enable it >> + */ >> + if (soc_type == QCA_QCA6390) >> + qca_send_enhancelog_enable_cmd(hdev); >> } else if (ret == -ENOENT) { >> /* No patch/nvm-config found, run with original fw/config */ >> ret = 0; >> @@ -1665,10 +1672,10 @@ static int qca_setup(struct hci_uart *hu) >> } >> >> /* Setup bdaddr */ >> - if (qca_is_wcn399x(soc_type)) >> - hu->hdev->set_bdaddr = qca_set_bdaddr; >> - else >> + if (soc_type == QCA_ROME) >> hu->hdev->set_bdaddr = qca_set_bdaddr_rome; >> + else >> + hu->hdev->set_bdaddr = qca_set_bdaddr; >> >> return ret; >> } >> @@ -1721,6 +1728,11 @@ static const struct qca_vreg_data >> qca_soc_data_wcn3998 = { >> .num_vregs = 4, >> }; >> >> +static const struct qca_vreg_data qca_soc_data_qca6390 = { >> + .soc_type = QCA_QCA6390, >> + .num_vregs = 0, >> +}; >> + >> static void qca_power_shutdown(struct hci_uart *hu) >> { >> struct qca_serdev *qcadev; >> @@ -1764,7 +1776,7 @@ static int qca_power_off(struct hci_dev *hdev) >> enum qca_btsoc_type soc_type = qca_soc_type(hu); >> >> /* Stop sending shutdown command if soc crashes. */ >> - if (qca_is_wcn399x(soc_type) >> + if (soc_type != QCA_ROME >> && qca->memdump_state == QCA_MEMDUMP_IDLE) { >> qca_send_pre_shutdown_cmd(hdev); >> usleep_range(8000, 10000); >> @@ -1900,7 +1912,11 @@ static int qca_serdev_probe(struct >> serdev_device *serdev) >> return err; >> } >> } else { >> - qcadev->btsoc_type = QCA_ROME; >> + if (data) >> + qcadev->btsoc_type = data->soc_type; >> + else >> + qcadev->btsoc_type = QCA_ROME; >> + >> qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", >> GPIOD_OUT_LOW); >> if (!qcadev->bt_en) { >> @@ -2044,21 +2060,37 @@ static int __maybe_unused qca_resume(struct >> device *dev) >> >> static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume); >> >> +#ifdef CONFIG_OF >> static const struct of_device_id qca_bluetooth_of_match[] = { >> { .compatible = "qcom,qca6174-bt" }, >> + { .compatible = "qcom,qca6390-bt", .data = &qca_soc_data_qca6390}, >> { .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990}, >> { .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991}, >> { .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998}, >> { /* sentinel */ } >> }; >> MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); >> +#endif >> + >> +#ifdef CONFIG_ACPI >> +static const struct acpi_device_id qca_bluetooth_acpi_match[] = { >> + { "QCOM6390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >> + { "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >> + { "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >> + { "DLB26390", (kernel_ulong_t)&qca_soc_data_qca6390 }, >> + { }, >> +}; >> +MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match); >> +#endif >> + >> >> static struct serdev_device_driver qca_serdev_driver = { >> .probe = qca_serdev_probe, >> .remove = qca_serdev_remove, >> .driver = { >> .name = "hci_uart_qca", >> - .of_match_table = qca_bluetooth_of_match, >> + .of_match_table = of_match_ptr(qca_bluetooth_of_match), >> + .acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match), >> .pm = &qca_pm_ops, >> }, >> }; ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 1/2] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390 [not found] <20200314094328.3331-1-rjliao@codeaurora.org> 2020-03-16 15:04 ` bgodavar @ 2020-03-16 17:46 ` Matthias Kaehlcke 2020-03-23 1:51 ` Rocky Liao 1 sibling, 1 reply; 8+ messages in thread From: Matthias Kaehlcke @ 2020-03-16 17:46 UTC (permalink / raw) To: Rocky Liao Cc: marcel, johan.hedberg, linux-kernel, linux-bluetooth, linux-arm-msm, bgodavar, c-hbandi, hemantg On Sat, Mar 14, 2020 at 05:43:27PM +0800, Rocky Liao wrote: > This patch adds support for QCA6390, including the devicetree and acpi > compatible hwid matching, and patch/nvm downloading. > > Signed-off-by: Rocky Liao <rjliao@codeaurora.org> > --- > drivers/bluetooth/btqca.c | 44 +++++++++++++++++++++++++++++++---- > drivers/bluetooth/btqca.h | 8 +++++++ > drivers/bluetooth/hci_qca.c | 46 +++++++++++++++++++++++++++++++------ > 3 files changed, 86 insertions(+), 12 deletions(-) > > diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c > index a16845c0751d..ca126e499c58 100644 > --- a/drivers/bluetooth/btqca.c > +++ b/drivers/bluetooth/btqca.c > @@ -14,6 +14,9 @@ > > #define VERSION "0.1" > > +#define QCA_IS_3991_6390(soc_type) \ > + (soc_type == QCA_WCN3991 || soc_type == QCA_QCA6390) This macro style is 3991 or 6390 is pretty ugly, IMO it's worse than the problem it intends to solve. I would either just spell out what the macro does, or if that becomes to cumbersome (especially when more types are added) have a macro that checks a bitmask like: qca_soc_type_matches(soc_type, QCA_WCN3991 | QCA6390) For this the SoC types read from FW would have to be mapped to a bit for each SoC type, which could be done during initialization. Another alternative could be to have a set of flags that indicate if a SoC has certain characteristics (e.g. enhanced logging needs to be enabled), these flags could be set during initialization. > + > int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, > enum qca_btsoc_type soc_type) > { > @@ -32,7 +35,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, > * VSE event. WCN3991 sends version command response as a payload to > * command complete event. > */ > - if (soc_type == QCA_WCN3991) { > + if (QCA_IS_3991_6390(soc_type)) { > event_type = 0; > rlen += 1; > rtype = EDL_PATCH_VER_REQ_CMD; > @@ -69,7 +72,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, > goto out; > } > > - if (soc_type == QCA_WCN3991) > + if (QCA_IS_3991_6390(soc_type)) > memmove(&edl->data, &edl->data[1], sizeof(*ver)); > > ver = (struct qca_btsoc_version *)(edl->data); > @@ -138,6 +141,29 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) > } > EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); > > +int qca_send_enhancelog_enable_cmd(struct hci_dev *hdev) > +{ > + struct sk_buff *skb; > + int err; > + const u8 param[2] = {0x14, 0x01}; > + > + bt_dev_dbg(hdev, "QCA enhanced log enable cmd"); > + > + skb = __hci_cmd_sync_ev(hdev, QCA_ENHANCED_LOG_ENABLE_CMD, 2, > + param, HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT); > + > + if (IS_ERR(skb)) { > + err = PTR_ERR(skb); > + bt_dev_err(hdev, "Enhanced log enable cmd failed (%d)", err); > + return err; > + } > + > + kfree_skb(skb); > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(qca_send_enhancelog_enable_cmd); > + > static void qca_tlv_check_data(struct qca_fw_config *config, > const struct firmware *fw, enum qca_btsoc_type soc_type) > { > @@ -217,7 +243,7 @@ static void qca_tlv_check_data(struct qca_fw_config *config, > tlv_nvm->data[0] |= 0x80; > > /* UART Baud Rate */ > - if (soc_type == QCA_WCN3991) > + if (QCA_IS_3991_6390(soc_type)) > tlv_nvm->data[1] = nvm_baud_rate; > else > tlv_nvm->data[2] = nvm_baud_rate; > @@ -268,7 +294,7 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, > * VSE event. WCN3991 sends version command response as a payload to > * command complete event. > */ > - if (soc_type == QCA_WCN3991) { > + if (QCA_IS_3991_6390(soc_type)) { > event_type = 0; > rlen = sizeof(*edl); > rtype = EDL_PATCH_TLV_REQ_CMD; > @@ -301,7 +327,7 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, > err = -EIO; > } > > - if (soc_type == QCA_WCN3991) > + if (QCA_IS_3991_6390(soc_type)) > goto out; > > tlv_resp = (struct tlv_seg_resp *)(edl->data); > @@ -442,6 +468,11 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, > (soc_ver & 0x0000000f); > snprintf(config.fwname, sizeof(config.fwname), > "qca/crbtfw%02x.tlv", rom_ver); > + } else if (soc_type == QCA_QCA6390) { > + rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | > + (soc_ver & 0x0000000f); > + snprintf(config.fwname, sizeof(config.fwname), > + "qca/htbtfw%02x.tlv", rom_ver); > } else { > snprintf(config.fwname, sizeof(config.fwname), > "qca/rampatch_%08x.bin", soc_ver); > @@ -464,6 +495,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, > else if (qca_is_wcn399x(soc_type)) > snprintf(config.fwname, sizeof(config.fwname), > "qca/crnv%02x.bin", rom_ver); > + else if (soc_type == QCA_QCA6390) > + snprintf(config.fwname, sizeof(config.fwname), > + "qca/htnv%02x.bin", rom_ver); > else > snprintf(config.fwname, sizeof(config.fwname), > "qca/nvm_%08x.bin", soc_ver); > diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h > index e16a4d650597..bc703817c3d7 100644 > --- a/drivers/bluetooth/btqca.h > +++ b/drivers/bluetooth/btqca.h > @@ -14,6 +14,7 @@ > #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) > #define MAX_SIZE_PER_TLV_SEGMENT (243) > #define QCA_PRE_SHUTDOWN_CMD (0xFC08) > +#define QCA_ENHANCED_LOG_ENABLE_CMD (0xFC17) > > #define EDL_CMD_REQ_RES_EVT (0x00) > #define EDL_PATCH_VER_RES_EVT (0x19) > @@ -127,6 +128,7 @@ enum qca_btsoc_type { > QCA_WCN3990, > QCA_WCN3991, > QCA_WCN3998, > + QCA_QCA6390, QCA_QCAxxxx seems a bit redundant, why not call it QCA_6390 or QCA6390? I also wouldn't be opposed to scrap the QCA_ prefixes from the WCN399x types, this is the QCA Bluetooth driver, so it's pretty evident that these are Qualcomm chips. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 1/2] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390 2020-03-16 17:46 ` Matthias Kaehlcke @ 2020-03-23 1:51 ` Rocky Liao 0 siblings, 0 replies; 8+ messages in thread From: Rocky Liao @ 2020-03-23 1:51 UTC (permalink / raw) To: Matthias Kaehlcke Cc: marcel, johan.hedberg, linux-kernel, linux-bluetooth, linux-arm-msm, bgodavar, c-hbandi, hemantg, linux-bluetooth-owner 在 2020-03-17 01:46,Matthias Kaehlcke 写道: > On Sat, Mar 14, 2020 at 05:43:27PM +0800, Rocky Liao wrote: >> This patch adds support for QCA6390, including the devicetree and acpi >> compatible hwid matching, and patch/nvm downloading. >> >> Signed-off-by: Rocky Liao <rjliao@codeaurora.org> >> --- >> drivers/bluetooth/btqca.c | 44 +++++++++++++++++++++++++++++++---- >> drivers/bluetooth/btqca.h | 8 +++++++ >> drivers/bluetooth/hci_qca.c | 46 >> +++++++++++++++++++++++++++++++------ >> 3 files changed, 86 insertions(+), 12 deletions(-) >> >> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c >> index a16845c0751d..ca126e499c58 100644 >> --- a/drivers/bluetooth/btqca.c >> +++ b/drivers/bluetooth/btqca.c >> @@ -14,6 +14,9 @@ >> >> #define VERSION "0.1" >> >> +#define QCA_IS_3991_6390(soc_type) \ >> + (soc_type == QCA_WCN3991 || soc_type == QCA_QCA6390) > > This macro style is 3991 or 6390 is pretty ugly, IMO it's worse than > the > problem it intends to solve. > > I would either just spell out what the macro does, or if that becomes > to > cumbersome (especially when more types are added) have a macro that > checks > a bitmask like: > > qca_soc_type_matches(soc_type, QCA_WCN3991 | QCA6390) > > For this the SoC types read from FW would have to be mapped to a bit > for > each SoC type, which could be done during initialization. > > Another alternative could be to have a set of flags that indicate if a > SoC > has certain characteristics (e.g. enhanced logging needs to be > enabled), > these flags could be set during initialization. > I prefer to adopt Bala's suggestion to use soc_type >= QCA_WCN3991 >> + >> int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, >> enum qca_btsoc_type soc_type) >> { >> @@ -32,7 +35,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 >> *soc_version, >> * VSE event. WCN3991 sends version command response as a payload to >> * command complete event. >> */ >> - if (soc_type == QCA_WCN3991) { >> + if (QCA_IS_3991_6390(soc_type)) { >> event_type = 0; >> rlen += 1; >> rtype = EDL_PATCH_VER_REQ_CMD; >> @@ -69,7 +72,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 >> *soc_version, >> goto out; >> } >> >> - if (soc_type == QCA_WCN3991) >> + if (QCA_IS_3991_6390(soc_type)) >> memmove(&edl->data, &edl->data[1], sizeof(*ver)); >> >> ver = (struct qca_btsoc_version *)(edl->data); >> @@ -138,6 +141,29 @@ int qca_send_pre_shutdown_cmd(struct hci_dev >> *hdev) >> } >> EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); >> >> +int qca_send_enhancelog_enable_cmd(struct hci_dev *hdev) >> +{ >> + struct sk_buff *skb; >> + int err; >> + const u8 param[2] = {0x14, 0x01}; >> + >> + bt_dev_dbg(hdev, "QCA enhanced log enable cmd"); >> + >> + skb = __hci_cmd_sync_ev(hdev, QCA_ENHANCED_LOG_ENABLE_CMD, 2, >> + param, HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT); >> + >> + if (IS_ERR(skb)) { >> + err = PTR_ERR(skb); >> + bt_dev_err(hdev, "Enhanced log enable cmd failed (%d)", err); >> + return err; >> + } >> + >> + kfree_skb(skb); >> + >> + return 0; >> +} >> +EXPORT_SYMBOL_GPL(qca_send_enhancelog_enable_cmd); >> + >> static void qca_tlv_check_data(struct qca_fw_config *config, >> const struct firmware *fw, enum qca_btsoc_type soc_type) >> { >> @@ -217,7 +243,7 @@ static void qca_tlv_check_data(struct >> qca_fw_config *config, >> tlv_nvm->data[0] |= 0x80; >> >> /* UART Baud Rate */ >> - if (soc_type == QCA_WCN3991) >> + if (QCA_IS_3991_6390(soc_type)) >> tlv_nvm->data[1] = nvm_baud_rate; >> else >> tlv_nvm->data[2] = nvm_baud_rate; >> @@ -268,7 +294,7 @@ static int qca_tlv_send_segment(struct hci_dev >> *hdev, int seg_size, >> * VSE event. WCN3991 sends version command response as a payload to >> * command complete event. >> */ >> - if (soc_type == QCA_WCN3991) { >> + if (QCA_IS_3991_6390(soc_type)) { >> event_type = 0; >> rlen = sizeof(*edl); >> rtype = EDL_PATCH_TLV_REQ_CMD; >> @@ -301,7 +327,7 @@ static int qca_tlv_send_segment(struct hci_dev >> *hdev, int seg_size, >> err = -EIO; >> } >> >> - if (soc_type == QCA_WCN3991) >> + if (QCA_IS_3991_6390(soc_type)) >> goto out; >> >> tlv_resp = (struct tlv_seg_resp *)(edl->data); >> @@ -442,6 +468,11 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t >> baudrate, >> (soc_ver & 0x0000000f); >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/crbtfw%02x.tlv", rom_ver); >> + } else if (soc_type == QCA_QCA6390) { >> + rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | >> + (soc_ver & 0x0000000f); >> + snprintf(config.fwname, sizeof(config.fwname), >> + "qca/htbtfw%02x.tlv", rom_ver); >> } else { >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/rampatch_%08x.bin", soc_ver); >> @@ -464,6 +495,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t >> baudrate, >> else if (qca_is_wcn399x(soc_type)) >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/crnv%02x.bin", rom_ver); >> + else if (soc_type == QCA_QCA6390) >> + snprintf(config.fwname, sizeof(config.fwname), >> + "qca/htnv%02x.bin", rom_ver); >> else >> snprintf(config.fwname, sizeof(config.fwname), >> "qca/nvm_%08x.bin", soc_ver); >> diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h >> index e16a4d650597..bc703817c3d7 100644 >> --- a/drivers/bluetooth/btqca.h >> +++ b/drivers/bluetooth/btqca.h >> @@ -14,6 +14,7 @@ >> #define EDL_NVM_ACCESS_SET_REQ_CMD (0x01) >> #define MAX_SIZE_PER_TLV_SEGMENT (243) >> #define QCA_PRE_SHUTDOWN_CMD (0xFC08) >> +#define QCA_ENHANCED_LOG_ENABLE_CMD (0xFC17) >> >> #define EDL_CMD_REQ_RES_EVT (0x00) >> #define EDL_PATCH_VER_RES_EVT (0x19) >> @@ -127,6 +128,7 @@ enum qca_btsoc_type { >> QCA_WCN3990, >> QCA_WCN3991, >> QCA_WCN3998, >> + QCA_QCA6390, > > QCA_QCAxxxx seems a bit redundant, why not call it QCA_6390 or QCA6390? > I also wouldn't be opposed to scrap the QCA_ prefixes from the WCN399x > types, this is the QCA Bluetooth driver, so it's pretty evident that > these are Qualcomm chips. I would like to do this in a separate patch. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 1/2] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390 @ 2019-12-12 6:06 Rocky Liao 0 siblings, 0 replies; 8+ messages in thread From: Rocky Liao @ 2019-12-12 6:06 UTC (permalink / raw) To: marcel, johan.hedberg; +Cc: linux-kernel, linux-bluetooth, Rocky Liao This patch add support for QCA6390. Signed-off-by: Rocky Liao <rjliao@codeaurora.org> --- drivers/bluetooth/btqca.c | 32 +++++++++++++++++++++-------- drivers/bluetooth/btqca.h | 1 + drivers/bluetooth/hci_qca.c | 40 ++++++++++++++++++++++++++++++++++--- 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index ec69e5dd7bd3..75990223e5e3 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -13,6 +13,8 @@ #include "btqca.h" #define VERSION "0.1" +#define QCA_IS_3991_6390(soc_type) \ + ((soc_type == QCA_WCN3991) || (soc_type == QCA_QCA6390)) int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, enum qca_btsoc_type soc_type) @@ -32,7 +34,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, * VSE event. WCN3991 sends version command response as a payload to * command complete event. */ - if (soc_type == QCA_WCN3991) { + if (QCA_IS_3991_6390(soc_type)) { event_type = 0; rlen += 1; rtype = EDL_PATCH_VER_REQ_CMD; @@ -69,7 +71,7 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, goto out; } - if (soc_type == QCA_WCN3991) + if ((QCA_IS_3991_6390(soc_type))) memmove(&edl->data, &edl->data[1], sizeof(*ver)); ver = (struct qca_btsoc_version *)(edl->data); @@ -139,7 +141,7 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); static void qca_tlv_check_data(struct qca_fw_config *config, - const struct firmware *fw) + const struct firmware *fw, enum qca_btsoc_type soc_type) { const u8 *data; u32 type_len; @@ -148,6 +150,7 @@ static void qca_tlv_check_data(struct qca_fw_config *config, struct tlv_type_hdr *tlv; struct tlv_type_patch *tlv_patch; struct tlv_type_nvm *tlv_nvm; + uint8_t nvm_baud_rate = config->user_baud_rate; tlv = (struct tlv_type_hdr *)fw->data; @@ -213,10 +216,14 @@ static void qca_tlv_check_data(struct qca_fw_config *config, * enabling software inband sleep * onto controller side. */ - tlv_nvm->data[0] |= 0x80; + if (!QCA_IS_3991_6390(soc_type)) + tlv_nvm->data[0] |= 0x80; /* UART Baud Rate */ - tlv_nvm->data[2] = config->user_baud_rate; + if ((QCA_IS_3991_6390(soc_type))) + tlv_nvm->data[1] = nvm_baud_rate; + else + tlv_nvm->data[2] = nvm_baud_rate; break; @@ -264,7 +271,7 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, * VSE event. WCN3991 sends version command response as a payload to * command complete event. */ - if (soc_type == QCA_WCN3991) { + if ((QCA_IS_3991_6390(soc_type))) { event_type = 0; rlen = sizeof(*edl); rtype = EDL_PATCH_TLV_REQ_CMD; @@ -297,7 +304,7 @@ static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, err = -EIO; } - if (soc_type == QCA_WCN3991) + if ((QCA_IS_3991_6390(soc_type))) goto out; tlv_resp = (struct tlv_seg_resp *)(edl->data); @@ -354,7 +361,7 @@ static int qca_download_firmware(struct hci_dev *hdev, return ret; } - qca_tlv_check_data(config, fw); + qca_tlv_check_data(config, fw, soc_type); segment = fw->data; remain = fw->size; @@ -438,6 +445,12 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, (soc_ver & 0x0000000f); snprintf(config.fwname, sizeof(config.fwname), "qca/crbtfw%02x.tlv", rom_ver); + } else if (soc_type == QCA_QCA6390) { + rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | + (soc_ver & 0x0000000f); + snprintf(config.fwname, sizeof(config.fwname), + "qca/htbtfw%02x.tlv", rom_ver); + } else { snprintf(config.fwname, sizeof(config.fwname), "qca/rampatch_%08x.bin", soc_ver); @@ -460,6 +473,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, else if (qca_is_wcn399x(soc_type)) snprintf(config.fwname, sizeof(config.fwname), "qca/crnv%02x.bin", rom_ver); + else if (soc_type == QCA_QCA6390) + snprintf(config.fwname, sizeof(config.fwname), + "qca/htnv%02x.bin", rom_ver); else snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin", soc_ver); diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index f5795b1a3779..2f06ed7e1c50 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -127,6 +127,7 @@ enum qca_btsoc_type { QCA_WCN3990, QCA_WCN3991, QCA_WCN3998, + QCA_QCA6390, }; #if IS_ENABLED(CONFIG_BT_QCA) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index f10bdf8e1fc5..472f468145e8 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -25,6 +25,7 @@ #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/of_device.h> +#include <linux/acpi.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/serdev.h> @@ -1355,6 +1356,16 @@ static const struct hci_uart_proto qca_proto = { .dequeue = qca_dequeue, }; +static const struct qca_vreg_data qca_soc_data_qca6174 = { + .soc_type = QCA_ROME, + .num_vregs = 0, +}; + +static const struct qca_vreg_data qca_soc_data_qca6390 = { + .soc_type = QCA_QCA6390, + .num_vregs = 0, +}; + static const struct qca_vreg_data qca_soc_data_wcn3990 = { .soc_type = QCA_WCN3990, .vregs = (struct qca_vreg []) { @@ -1501,7 +1512,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) return -ENOMEM; qcadev->serdev_hu.serdev = serdev; - data = of_device_get_match_data(&serdev->dev); + data = device_get_match_data(&serdev->dev); serdev_device_set_drvdata(serdev, qcadev); device_property_read_string(&serdev->dev, "firmware-name", &qcadev->firmware_name); @@ -1534,7 +1545,10 @@ static int qca_serdev_probe(struct serdev_device *serdev) goto out; } } else { - qcadev->btsoc_type = QCA_ROME; + if (data) + qcadev->btsoc_type = data->soc_type; + else + qcadev->btsoc_type = QCA_ROME; qcadev->bt_en = devm_gpiod_get(&serdev->dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(qcadev->bt_en)) { @@ -1670,21 +1684,41 @@ static int __maybe_unused qca_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume); +#ifdef CONFIG_OF static const struct of_device_id qca_bluetooth_of_match[] = { - { .compatible = "qcom,qca6174-bt" }, + { .compatible = "qcom,qca6174-bt" .data = &qca_soc_data_qca6174}, + { .compatible = "qcom,qca6390-bt" .data = &qca_soc_data_qca6390}, { .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990}, { .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991}, { .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998}, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); +#endif + +#ifdef CONFIG_ACPI +static const struct acpi_device_id qca_bluetooth_acpi_match[] = { + { "QCOM6390", (kernel_ulong_t)&qca_soc_data_qca6390 }, + { "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, + { "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 }, + { "DLB26390", (kernel_ulong_t)&qca_soc_data_qca6390 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, qca_bluetooth_acpi_match); +#endif + static struct serdev_device_driver qca_serdev_driver = { .probe = qca_serdev_probe, .remove = qca_serdev_remove, .driver = { .name = "hci_uart_qca", + #ifdef CONFIG_OF .of_match_table = qca_bluetooth_of_match, + #endif + #ifdef CONFIG_ACPI + .acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match), + #endif .pm = &qca_pm_ops, }, }; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-03-23 9:12 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <0101016ef8b72eb9-c2212883-72cf-4f02-9f5d-078135c7085e-000000@us-west-2.amazonses.com>
2019-12-12 10:32 ` [PATCH v1 1/2] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth SoC QCA6390 Marcel Holtmann
2019-12-13 3:33 ` rjliao
[not found] ` <471977a5037f06093945c5e71c78e538@codeaurora.org>
2019-12-13 7:41 ` Marcel Holtmann
[not found] <20200314094328.3331-1-rjliao@codeaurora.org>
2020-03-16 15:04 ` bgodavar
2020-03-23 9:12 ` Rocky Liao
2020-03-16 17:46 ` Matthias Kaehlcke
2020-03-23 1:51 ` Rocky Liao
2019-12-12 6:06 Rocky Liao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).