From patchwork Fri Aug 3 12:16:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Balakrishna Godavarthi X-Patchwork-Id: 10555057 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 93BED14E2 for ; Fri, 3 Aug 2018 12:17:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 86C0E2B916 for ; Fri, 3 Aug 2018 12:17:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7A6BF2B994; Fri, 3 Aug 2018 12:17:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CADD52B916 for ; Fri, 3 Aug 2018 12:17:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729474AbeHCOMw (ORCPT ); Fri, 3 Aug 2018 10:12:52 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:44946 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727566AbeHCOMw (ORCPT ); Fri, 3 Aug 2018 10:12:52 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 01A9460117; Fri, 3 Aug 2018 12:16:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298607; bh=qFfW7N0fvbHZC+fvqPkhQh3yVLJhRHmrI0DJ8I/W7kE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i0WDVvslnqBmtvuviMU1NXm6uxD9CNAemiTkmZk+mFPcYgdpaGjpmgmXvoKERDrlP DDRtzbb2e9stEAlfgly0/enxeQo06jNiX/oG3zxkDXIEyRQquo3l73w8H+y5mwjMT8 asc0xJ5psVWGPb3vzRDA4td1ACL15mI9QCHvW8no= Received: from bgodavar-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: bgodavar@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id DEE69602D7; Fri, 3 Aug 2018 12:16:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298606; bh=qFfW7N0fvbHZC+fvqPkhQh3yVLJhRHmrI0DJ8I/W7kE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mSudnDs8K0ixe8eRlxeOQFM9iY4spBN919UPSAFjyxXU77944o59F+zBz++bEA+Oc vD1JaN0FVgJWAfW7rGEIW/UcI/WNV2SKWuVllBjAvcBA2xQHMXgC1KkBLPqaVyenKf EpWLwIRt1+VgtNAdEKtVjM9IFHiqrcDyB/vcSK3k= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org DEE69602D7 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=bgodavar@codeaurora.org From: Balakrishna Godavarthi To: marcel@holtmann.org, johan.hedberg@gmail.com, mka@chromium.org Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-bluetooth@vger.kernel.org, thierry.escande@linaro.org, rtatiya@codeaurora.org, hemantg@codeaurora.org, linux-arm-msm@vger.kernel.org, Balakrishna Godavarthi Subject: [PATCH v15 1/7] dt-bindings: net: bluetooth: Add device tree bindings for QTI chip wcn3990 Date: Fri, 3 Aug 2018 17:46:26 +0530 Message-Id: <20180803121632.30689-2-bgodavar@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180803121632.30689-1-bgodavar@codeaurora.org> References: <20180803121632.30689-1-bgodavar@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch enables regulators for the Qualcomm Bluetooth wcn3990 controller. Signed-off-by: Balakrishna Godavarthi Reviewed-by: Rob Herring Reviewed-by: Stephen Boyd Reviewed-by: Matthias Kaehlcke --- .../bindings/net/qualcomm-bluetooth.txt | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt b/Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt index 0ea18a53cc29..824c0e23c544 100644 --- a/Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt +++ b/Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt @@ -10,12 +10,25 @@ device the slave device is attached to. Required properties: - compatible: should contain one of the following: * "qcom,qca6174-bt" + * "qcom,wcn3990-bt" + +Optional properties for compatible string qcom,qca6174-bt: -Optional properties: - enable-gpios: gpio specifier used to enable chip - clocks: clock provided to the controller (SUSCLK_32KHZ) -Example: +Required properties for compatible string qcom,wcn3990-bt: + + - vddio-supply: VDD_IO supply regulator handle. + - vddxo-supply: VDD_XO supply regulator handle. + - vddrf-supply: VDD_RF supply regulator handle. + - vddch0-supply: VDD_CH0 supply regulator handle. + +Optional properties for compatible string qcom,wcn3990-bt: + + - max-speed: see Documentation/devicetree/bindings/serial/slave-device.txt + +Examples: serial@7570000 { label = "BT-UART"; @@ -28,3 +41,15 @@ serial@7570000 { clocks = <&divclk4>; }; }; + +serial@898000 { + bluetooth { + compatible = "qcom,wcn3990-bt"; + + vddio-supply = <&vreg_s4a_1p8>; + vddxo-supply = <&vreg_l7a_1p8>; + vddrf-supply = <&vreg_l17a_1p3>; + vddch0-supply = <&vreg_l25a_3p3>; + max-speed = <3200000>; + }; +}; From patchwork Fri Aug 3 12:16:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Balakrishna Godavarthi X-Patchwork-Id: 10555045 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0F22413AC for ; Fri, 3 Aug 2018 12:16:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0374C2B8FF for ; Fri, 3 Aug 2018 12:16:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EAF472B994; Fri, 3 Aug 2018 12:16:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C58EB2B8FF for ; Fri, 3 Aug 2018 12:16:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729881AbeHCOM5 (ORCPT ); Fri, 3 Aug 2018 10:12:57 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:45060 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728139AbeHCOM4 (ORCPT ); Fri, 3 Aug 2018 10:12:56 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id B70CC6074D; Fri, 3 Aug 2018 12:16:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298611; bh=5X2eNohUsJIF9U4TztuytLq+TzBPAxvDsEhNVgbxy+g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QODzoA37ZLqUzgTpc2gpiNeqxYZuNiwQHgw2/DuQQ9TvMgbz5NlizBkHnbuLUqsBE NztWQIO48Mw6iqFzB6ovg6/UkAUQ904gNfVPWsLoSZPFaa9cr9Ty8zlppIuH8d3fFs kKvibiZr9Ga1JarauPhr5ozlofWqDnb2JdoLS670= Received: from bgodavar-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: bgodavar@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id A5A0760AD8; Fri, 3 Aug 2018 12:16:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298610; bh=5X2eNohUsJIF9U4TztuytLq+TzBPAxvDsEhNVgbxy+g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HMxA1bzedoEtikEWwFtP4kKKLCFPVzBcoEJqPqmI7f1+2DFoLHYp0pB4woWuYSPU9 eN1RRY6TE9WTmbmMIXaS200nZb0AgdO7fGQ4OPqRGMTODlEQ38uXOuNDL+7bngnoU2 unqMSjHTqDUCOeM4zCoa9QTVTN8YOLBHkHHmokVk= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org A5A0760AD8 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=bgodavar@codeaurora.org From: Balakrishna Godavarthi To: marcel@holtmann.org, johan.hedberg@gmail.com, mka@chromium.org Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-bluetooth@vger.kernel.org, thierry.escande@linaro.org, rtatiya@codeaurora.org, hemantg@codeaurora.org, linux-arm-msm@vger.kernel.org, Balakrishna Godavarthi Subject: [PATCH v15 2/7] Bluetooth: btqca: Rename ROME specific functions to generic functions Date: Fri, 3 Aug 2018 17:46:27 +0530 Message-Id: <20180803121632.30689-3-bgodavar@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180803121632.30689-1-bgodavar@codeaurora.org> References: <20180803121632.30689-1-bgodavar@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Some of the QCA BTSoC ROME functions, are used for different versions or different make of BTSoC's. Instead of duplicating the same functions for new chip, update names of the functions that are used for both chips to keep this generic and would help in future when we would have new BT SoC. To have generic text in logs updated from ROME to QCA where ever possible. This avoids confusion to user, when using the future Qualcomm Bluetooth SoC's. Updated BT_DBG, BT_ERR and BT_INFO with bt_dev_dbg, bt_dev_err and bt_dev_info where ever applicable. Signed-off-by: Balakrishna Godavarthi Reviewed-by: Matthias Kaehlcke --- drivers/bluetooth/btqca.c | 85 ++++++++++++++++++------------------- drivers/bluetooth/btqca.h | 10 ++++- drivers/bluetooth/hci_qca.c | 2 +- 3 files changed, 51 insertions(+), 46 deletions(-) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 8219816c54a0..c5cf9cab438a 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -27,7 +27,7 @@ #define VERSION "0.1" -static int rome_patch_ver_req(struct hci_dev *hdev, u32 *rome_version) +int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version) { struct sk_buff *skb; struct edl_event_hdr *edl; @@ -35,36 +35,35 @@ static int rome_patch_ver_req(struct hci_dev *hdev, u32 *rome_version) char cmd; int err = 0; - BT_DBG("%s: ROME Patch Version Request", hdev->name); + bt_dev_dbg(hdev, "QCA Version Request"); cmd = EDL_PATCH_VER_REQ_CMD; skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN, &cmd, HCI_VENDOR_PKT, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { err = PTR_ERR(skb); - BT_ERR("%s: Failed to read version of ROME (%d)", hdev->name, - err); + bt_dev_err(hdev, "Reading QCA version information failed (%d)", + err); return err; } if (skb->len != sizeof(*edl) + sizeof(*ver)) { - BT_ERR("%s: Version size mismatch len %d", hdev->name, - skb->len); + bt_dev_err(hdev, "QCA Version size mismatch len %d", skb->len); err = -EILSEQ; goto out; } edl = (struct edl_event_hdr *)(skb->data); if (!edl) { - BT_ERR("%s: TLV with no header", hdev->name); + bt_dev_err(hdev, "QCA TLV with no header"); err = -EILSEQ; goto out; } if (edl->cresp != EDL_CMD_REQ_RES_EVT || edl->rtype != EDL_APP_VER_RES_EVT) { - BT_ERR("%s: Wrong packet received %d %d", hdev->name, - edl->cresp, edl->rtype); + bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp, + edl->rtype); err = -EIO; goto out; } @@ -76,11 +75,11 @@ static int rome_patch_ver_req(struct hci_dev *hdev, u32 *rome_version) BT_DBG("%s: ROM :0x%08x", hdev->name, le16_to_cpu(ver->rome_ver)); BT_DBG("%s: SOC :0x%08x", hdev->name, le32_to_cpu(ver->soc_id)); - /* ROME chipset version can be decided by patch and SoC + /* QCA chipset version can be decided by patch and SoC * version, combination with upper 2 bytes from SoC * and lower 2 bytes from patch will be used. */ - *rome_version = (le32_to_cpu(ver->soc_id) << 16) | + *soc_version = (le32_to_cpu(ver->soc_id) << 16) | (le16_to_cpu(ver->rome_ver) & 0x0000ffff); out: @@ -88,18 +87,19 @@ static int rome_patch_ver_req(struct hci_dev *hdev, u32 *rome_version) return err; } +EXPORT_SYMBOL_GPL(qca_read_soc_version); -static int rome_reset(struct hci_dev *hdev) +static int qca_send_reset(struct hci_dev *hdev) { struct sk_buff *skb; int err; - BT_DBG("%s: ROME HCI_RESET", hdev->name); + bt_dev_dbg(hdev, "QCA HCI_RESET"); skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { err = PTR_ERR(skb); - BT_ERR("%s: Reset failed (%d)", hdev->name, err); + bt_dev_err(hdev, "QCA Reset failed (%d)", err); return err; } @@ -108,7 +108,7 @@ static int rome_reset(struct hci_dev *hdev) return 0; } -static void rome_tlv_check_data(struct rome_config *config, +static void qca_tlv_check_data(struct rome_config *config, const struct firmware *fw) { const u8 *data; @@ -207,7 +207,7 @@ static void rome_tlv_check_data(struct rome_config *config, } } -static int rome_tlv_send_segment(struct hci_dev *hdev, int seg_size, +static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size, const u8 *data, enum rome_tlv_dnld_mode mode) { struct sk_buff *skb; @@ -228,19 +228,19 @@ static int rome_tlv_send_segment(struct hci_dev *hdev, int seg_size, HCI_VENDOR_PKT, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { err = PTR_ERR(skb); - BT_ERR("%s: Failed to send TLV segment (%d)", hdev->name, err); + bt_dev_err(hdev, "QCA Failed to send TLV segment (%d)", err); return err; } if (skb->len != sizeof(*edl) + sizeof(*tlv_resp)) { - BT_ERR("%s: TLV response size mismatch", hdev->name); + bt_dev_err(hdev, "QCA TLV response size mismatch"); err = -EILSEQ; goto out; } edl = (struct edl_event_hdr *)(skb->data); if (!edl) { - BT_ERR("%s: TLV with no header", hdev->name); + bt_dev_err(hdev, "TLV with no header"); err = -EILSEQ; goto out; } @@ -249,8 +249,8 @@ static int rome_tlv_send_segment(struct hci_dev *hdev, int seg_size, if (edl->cresp != EDL_CMD_REQ_RES_EVT || edl->rtype != EDL_TVL_DNLD_RES_EVT || tlv_resp->result != 0x00) { - BT_ERR("%s: TLV with error stat 0x%x rtype 0x%x (0x%x)", - hdev->name, edl->cresp, edl->rtype, tlv_resp->result); + bt_dev_err(hdev, "QCA TLV with error stat 0x%x rtype 0x%x (0x%x)", + edl->cresp, edl->rtype, tlv_resp->result); err = -EIO; } @@ -260,23 +260,23 @@ static int rome_tlv_send_segment(struct hci_dev *hdev, int seg_size, return err; } -static int rome_download_firmware(struct hci_dev *hdev, +static int qca_download_firmware(struct hci_dev *hdev, struct rome_config *config) { const struct firmware *fw; const u8 *segment; int ret, remain, i = 0; - bt_dev_info(hdev, "ROME Downloading %s", config->fwname); + bt_dev_info(hdev, "QCA Downloading %s", config->fwname); ret = request_firmware(&fw, config->fwname, &hdev->dev); if (ret) { - BT_ERR("%s: Failed to request file: %s (%d)", hdev->name, - config->fwname, ret); + bt_dev_err(hdev, "QCA Failed to request file: %s (%d)", + config->fwname, ret); return ret; } - rome_tlv_check_data(config, fw); + qca_tlv_check_data(config, fw); segment = fw->data; remain = fw->size; @@ -290,7 +290,7 @@ static int rome_download_firmware(struct hci_dev *hdev, if (!remain || segsize < MAX_SIZE_PER_TLV_SEGMENT) config->dnld_mode = ROME_SKIP_EVT_NONE; - ret = rome_tlv_send_segment(hdev, segsize, segment, + ret = qca_tlv_send_segment(hdev, segsize, segment, config->dnld_mode); if (ret) break; @@ -317,8 +317,7 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) HCI_VENDOR_PKT, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { err = PTR_ERR(skb); - BT_ERR("%s: Change address command failed (%d)", - hdev->name, err); + bt_dev_err(hdev, "QCA Change address command failed (%d)", err); return err; } @@ -328,32 +327,32 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr) } EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome); -int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate) +int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate) { u32 rome_ver = 0; struct rome_config config; int err; - BT_DBG("%s: ROME setup on UART", hdev->name); + bt_dev_dbg(hdev, "QCA setup on UART"); config.user_baud_rate = baudrate; - /* Get ROME version information */ - err = rome_patch_ver_req(hdev, &rome_ver); + /* Get QCA version information */ + err = qca_read_soc_version(hdev, &rome_ver); if (err < 0 || rome_ver == 0) { - BT_ERR("%s: Failed to get version 0x%x", hdev->name, err); + bt_dev_err(hdev, "QCA Failed to get version %d", err); return err; } - bt_dev_info(hdev, "ROME controller version 0x%08x", rome_ver); + bt_dev_info(hdev, "QCA controller version 0x%08x", rome_ver); /* Download rampatch file */ config.type = TLV_TYPE_PATCH; snprintf(config.fwname, sizeof(config.fwname), "qca/rampatch_%08x.bin", rome_ver); - err = rome_download_firmware(hdev, &config); + err = qca_download_firmware(hdev, &config); if (err < 0) { - BT_ERR("%s: Failed to download patch (%d)", hdev->name, err); + bt_dev_err(hdev, "QCA Failed to download patch (%d)", err); return err; } @@ -361,24 +360,24 @@ int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate) config.type = TLV_TYPE_NVM; snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin", rome_ver); - err = rome_download_firmware(hdev, &config); + err = qca_download_firmware(hdev, &config); if (err < 0) { - BT_ERR("%s: Failed to download NVM (%d)", hdev->name, err); + bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err); return err; } /* Perform HCI reset */ - err = rome_reset(hdev); + err = qca_send_reset(hdev); if (err < 0) { - BT_ERR("%s: Failed to run HCI_RESET (%d)", hdev->name, err); + bt_dev_err(hdev, "QCA Failed to run HCI_RESET (%d)", err); return err; } - bt_dev_info(hdev, "ROME setup on UART is completed"); + bt_dev_info(hdev, "QCA setup on UART is completed"); return 0; } -EXPORT_SYMBOL_GPL(qca_uart_setup_rome); +EXPORT_SYMBOL_GPL(qca_uart_setup); MODULE_AUTHOR("Ben Young Tae Kim "); MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " VERSION); diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index 13d77fd873b6..5c9851b11838 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -127,7 +127,8 @@ struct tlv_type_hdr { #if IS_ENABLED(CONFIG_BT_QCA) int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr); -int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate); +int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate); +int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version); #else @@ -136,7 +137,12 @@ static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdad return -EOPNOTSUPP; } -static inline int qca_uart_setup_rome(struct hci_dev *hdev, int speed) +static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate) +{ + return -EOPNOTSUPP; +} + +static inline int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version) { return -EOPNOTSUPP; } diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 51790dd02afb..d7b60669b656 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -966,7 +966,7 @@ static int qca_setup(struct hci_uart *hu) } /* Setup patch / NVM configurations */ - ret = qca_uart_setup_rome(hdev, qca_baudrate); + ret = qca_uart_setup(hdev, qca_baudrate); if (!ret) { set_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags); qca_debugfs_init(hdev); From patchwork Fri Aug 3 12:16:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Balakrishna Godavarthi X-Patchwork-Id: 10555047 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 945A8A637 for ; Fri, 3 Aug 2018 12:16:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 884372B8FF for ; Fri, 3 Aug 2018 12:16:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7C27C2B916; Fri, 3 Aug 2018 12:16:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 634C72B90C for ; Fri, 3 Aug 2018 12:16:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730783AbeHCONA (ORCPT ); Fri, 3 Aug 2018 10:13:00 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:45160 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728139AbeHCONA (ORCPT ); Fri, 3 Aug 2018 10:13:00 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 92AB1606DD; Fri, 3 Aug 2018 12:16:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298614; bh=c+IM+STRfSG1SwRsEuJBwWeGjee4Q5OItKRpd4xqfQM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OQITbkpao2Y4AVfJE/zjLQaVmJ92QCi4jNpHbXBGOOpnmq+6FTqS6eXMgFa1z4Loo yiHDIkq1hkZ3/X8lT9z9nLRm3W1yzobBg74KYjIMWPOOQHaMU8b/94dGPg0SSkI2nd OIwT7amB1Z0fwRu1Dhsb/EyVE3KGRZEqtdRQWHPM= Received: from bgodavar-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: bgodavar@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id AD7EC6031A; Fri, 3 Aug 2018 12:16:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298613; bh=c+IM+STRfSG1SwRsEuJBwWeGjee4Q5OItKRpd4xqfQM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d3HY/Q0t/6TNIl7JXcbfNa4a9j6LOtfIedFAUBVih+KEH9glf7OF2bape2X97dl64 nDGJ5eGERpIHdyiwpTqOxmsQTAV2iMDF3wRJxFZ7sMMEYlBeuAx2kDm/haDaDODQ/v 7SfPDtN7Czxdsl7sZqddWWLMdfARb8aDhivaiWL4= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org AD7EC6031A Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=bgodavar@codeaurora.org From: Balakrishna Godavarthi To: marcel@holtmann.org, johan.hedberg@gmail.com, mka@chromium.org Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-bluetooth@vger.kernel.org, thierry.escande@linaro.org, rtatiya@codeaurora.org, hemantg@codeaurora.org, linux-arm-msm@vger.kernel.org, Balakrishna Godavarthi Subject: [PATCH v15 3/7] Bluetooth: btqca: Redefine qca_uart_setup() to generic function. Date: Fri, 3 Aug 2018 17:46:28 +0530 Message-Id: <20180803121632.30689-4-bgodavar@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180803121632.30689-1-bgodavar@codeaurora.org> References: <20180803121632.30689-1-bgodavar@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Redefinition of qca_uart_setup will help future Qualcomm Bluetooth SoC, to use the same function instead of duplicating the function. Added new arguments soc_type and soc_ver to the functions. These arguments will help to decide type of firmware files to be loaded into Bluetooth chip. soc_type holds the Bluetooth chip connected to APPS processor. soc_ver holds the Bluetooth chip version. Signed-off-by: Balakrishna Godavarthi Reviewed-by: Matthias Kaehlcke --- drivers/bluetooth/btqca.c | 21 ++++++++------------- drivers/bluetooth/btqca.h | 13 +++++++++++-- drivers/bluetooth/hci_qca.c | 10 +++++++++- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index c5cf9cab438a..479179c54dcf 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -81,9 +81,13 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version) */ *soc_version = (le32_to_cpu(ver->soc_id) << 16) | (le16_to_cpu(ver->rome_ver) & 0x0000ffff); + if (*soc_version == 0) + err = -EILSEQ; out: kfree_skb(skb); + if (err) + bt_dev_err(hdev, "QCA Failed to get version (%d)", err); return err; } @@ -327,9 +331,9 @@ 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) +int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + enum qca_btsoc_type soc_type, u32 soc_ver) { - u32 rome_ver = 0; struct rome_config config; int err; @@ -337,19 +341,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate) config.user_baud_rate = baudrate; - /* Get QCA version information */ - err = qca_read_soc_version(hdev, &rome_ver); - if (err < 0 || rome_ver == 0) { - bt_dev_err(hdev, "QCA Failed to get version %d", err); - return err; - } - - bt_dev_info(hdev, "QCA controller version 0x%08x", rome_ver); - /* Download rampatch file */ config.type = TLV_TYPE_PATCH; snprintf(config.fwname, sizeof(config.fwname), "qca/rampatch_%08x.bin", - rome_ver); + soc_ver); err = qca_download_firmware(hdev, &config); if (err < 0) { bt_dev_err(hdev, "QCA Failed to download patch (%d)", err); @@ -359,7 +354,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate) /* Download NVM configuration */ config.type = TLV_TYPE_NVM; snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin", - rome_ver); + soc_ver); err = qca_download_firmware(hdev, &config); if (err < 0) { bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err); diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index 5c9851b11838..a9c2779f3e07 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -124,10 +124,18 @@ struct tlv_type_hdr { __u8 data[0]; } __packed; +enum qca_btsoc_type { + QCA_INVALID = -1, + QCA_AR3002, + QCA_ROME, + QCA_WCN3990 +}; + #if IS_ENABLED(CONFIG_BT_QCA) int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr); -int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate); +int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + enum qca_btsoc_type soc_type, u32 soc_ver); int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version); #else @@ -137,7 +145,8 @@ static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdad return -EOPNOTSUPP; } -static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate) +static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, + enum qca_btsoc_type soc_type, u32 soc_ver) { return -EOPNOTSUPP; } diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index d7b60669b656..5f1c0a8fd5cd 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -929,6 +929,7 @@ static int qca_setup(struct hci_uart *hu) struct qca_data *qca = hu->priv; unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200; int ret; + int soc_ver = 0; bt_dev_info(hdev, "ROME setup"); @@ -965,8 +966,15 @@ static int qca_setup(struct hci_uart *hu) host_set_baudrate(hu, speed); } + /* Get QCA version information */ + ret = qca_read_soc_version(hdev, &soc_ver); + if (ret) + return ret; + + bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver); + /* Setup patch / NVM configurations */ - ret = qca_uart_setup(hdev, qca_baudrate); + ret = qca_uart_setup(hdev, qca_baudrate, QCA_ROME, soc_ver); if (!ret) { set_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags); qca_debugfs_init(hdev); From patchwork Fri Aug 3 12:16:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Balakrishna Godavarthi X-Patchwork-Id: 10555055 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CC0551822 for ; Fri, 3 Aug 2018 12:17:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C19C12B90C for ; Fri, 3 Aug 2018 12:17:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B5F9F2B984; Fri, 3 Aug 2018 12:17:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 499442B90C for ; Fri, 3 Aug 2018 12:17:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730822AbeHCONE (ORCPT ); Fri, 3 Aug 2018 10:13:04 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:45310 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727403AbeHCONE (ORCPT ); Fri, 3 Aug 2018 10:13:04 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id F3BE3607BD; Fri, 3 Aug 2018 12:16:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298619; bh=Zsi/y3FYCzIxxLpLK8ynqd4qhjN6NLR3ux4gMLn85FM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cccKVYOyXgsMj78E02fqSWO7+P5GOV6z96dvGYkFxryinEbLo7uyGC5EGFiMyiQQP ucKlItne3jGYNQdVwDOFXQUWwJi7pZOe7DwAEaTzPPMtINghpyFaLJo2u0U0b1weDV hNyxpxcn+GtX35+hngR9c3aAClYlRwxKn8mgQQ9Y= Received: from bgodavar-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: bgodavar@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 75BD560AD8; Fri, 3 Aug 2018 12:16:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298617; bh=Zsi/y3FYCzIxxLpLK8ynqd4qhjN6NLR3ux4gMLn85FM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DYfiza4q67aGJu5mSDvivaDMA3sLAuIBlBfzV+OIWTwvtj7vegIugQpl8sHaNn+Zt WivNXuB2F12Mt4ZvDzUUtZ+4TzPMvL9ho+JxI9smuV1gOdmtp4uoh4TWg82JCWG2Yv p2kFvB/0fPgXMVZp7qdFdbiqWX208+TVAUcYJNqI= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 75BD560AD8 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=bgodavar@codeaurora.org From: Balakrishna Godavarthi To: marcel@holtmann.org, johan.hedberg@gmail.com, mka@chromium.org Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-bluetooth@vger.kernel.org, thierry.escande@linaro.org, rtatiya@codeaurora.org, hemantg@codeaurora.org, linux-arm-msm@vger.kernel.org, Balakrishna Godavarthi Subject: [PATCH v15 4/7] Bluetooth: hci_qca: Add wrapper functions for setting UART speed Date: Fri, 3 Aug 2018 17:46:29 +0530 Message-Id: <20180803121632.30689-5-bgodavar@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180803121632.30689-1-bgodavar@codeaurora.org> References: <20180803121632.30689-1-bgodavar@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In function qca_setup, we set initial and operating speeds for Qualcomm Bluetooth SoC's. This block of code is common across different Qualcomm Bluetooth SoC's. Instead of duplicating the code, created a wrapper function to set the speeds. So that future coming SoC's can use these wrapper functions to set speeds. Signed-off-by: Balakrishna Godavarthi Reviewed-by: Matthias Kaehlcke --- drivers/bluetooth/hci_qca.c | 93 ++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 23 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 5f1c0a8fd5cd..5f8a74d65bec 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -119,6 +119,11 @@ struct qca_data { u64 votes_off; }; +enum qca_speed_type { + QCA_INIT_SPEED = 1, + QCA_OPER_SPEED +}; + struct qca_serdev { struct hci_uart serdev_hu; struct gpio_desc *bt_en; @@ -923,6 +928,61 @@ static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed) hci_uart_set_baudrate(hu, speed); } +static unsigned int qca_get_speed(struct hci_uart *hu, + enum qca_speed_type speed_type) +{ + unsigned int speed = 0; + + if (speed_type == QCA_INIT_SPEED) { + if (hu->init_speed) + speed = hu->init_speed; + else if (hu->proto->init_speed) + speed = hu->proto->init_speed; + } else { + if (hu->oper_speed) + speed = hu->oper_speed; + else if (hu->proto->oper_speed) + speed = hu->proto->oper_speed; + } + + return speed; +} + +static int qca_check_speeds(struct hci_uart *hu) +{ + if (!qca_get_speed(hu, QCA_INIT_SPEED) || + !qca_get_speed(hu, QCA_OPER_SPEED)) + return -EINVAL; + + return 0; +} + +static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) +{ + unsigned int speed, qca_baudrate; + int ret; + + if (speed_type == QCA_INIT_SPEED) { + speed = qca_get_speed(hu, QCA_INIT_SPEED); + if (speed) + host_set_baudrate(hu, speed); + } else { + speed = qca_get_speed(hu, QCA_OPER_SPEED); + if (!speed) + return 0; + + qca_baudrate = qca_get_baudrate_value(speed); + bt_dev_info(hu->hdev, "Set UART speed to %d", speed); + ret = qca_set_baudrate(hu->hdev, qca_baudrate); + if (ret) + return ret; + + host_set_baudrate(hu, speed); + } + + return 0; +} + static int qca_setup(struct hci_uart *hu) { struct hci_dev *hdev = hu->hdev; @@ -933,37 +993,24 @@ static int qca_setup(struct hci_uart *hu) bt_dev_info(hdev, "ROME setup"); + ret = qca_check_speeds(hu); + if (ret) + return ret; + /* Patch downloading has to be done without IBS mode */ clear_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags); /* Setup initial baudrate */ - speed = 0; - if (hu->init_speed) - speed = hu->init_speed; - else if (hu->proto->init_speed) - speed = hu->proto->init_speed; - - if (speed) - host_set_baudrate(hu, speed); + qca_set_speed(hu, QCA_INIT_SPEED); /* Setup user speed if needed */ - speed = 0; - if (hu->oper_speed) - speed = hu->oper_speed; - else if (hu->proto->oper_speed) - speed = hu->proto->oper_speed; - + speed = qca_get_speed(hu, QCA_OPER_SPEED); if (speed) { - qca_baudrate = qca_get_baudrate_value(speed); - - bt_dev_info(hdev, "Set UART speed to %d", speed); - ret = qca_set_baudrate(hdev, qca_baudrate); - if (ret) { - bt_dev_err(hdev, "Failed to change the baud rate (%d)", - ret); + ret = qca_set_speed(hu, QCA_OPER_SPEED); + if (ret) return ret; - } - host_set_baudrate(hu, speed); + + qca_baudrate = qca_get_baudrate_value(speed); } /* Get QCA version information */ From patchwork Fri Aug 3 12:16:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Balakrishna Godavarthi X-Patchwork-Id: 10555053 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E9B661822 for ; Fri, 3 Aug 2018 12:17:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DE6C12B916 for ; Fri, 3 Aug 2018 12:17:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D2F4C2B984; Fri, 3 Aug 2018 12:17:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 817B32B90C for ; Fri, 3 Aug 2018 12:17:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731447AbeHCONI (ORCPT ); Fri, 3 Aug 2018 10:13:08 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:45468 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727403AbeHCONH (ORCPT ); Fri, 3 Aug 2018 10:13:07 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 515C9602B7; Fri, 3 Aug 2018 12:17:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298623; bh=1Jdp7Zlr0OEA1yU9+iwqVJNjFakj/qigqjjsA79r2uU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eABV0rnKuG1n3cJZhMWHGAJaEC3m1f7DKwTE4dSsKe0D+pE0IG9vgwz0yvzn8sWe+ gFZUyucKdOlkpAvM1/RO52EdN2tpASQ8Hz86BdW5WcN5NGVKfMi4qIuAO3KxZ/IT3u XIHn2ZOhJg3SK6hAw266sf4IAcxBVtX49a+KHxj0= Received: from bgodavar-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: bgodavar@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 4BCCD6063A; Fri, 3 Aug 2018 12:16:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298621; bh=1Jdp7Zlr0OEA1yU9+iwqVJNjFakj/qigqjjsA79r2uU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mIY+zeikCeQVGbukyXzEtbTJ9eAxjxOEPCj4PlKx0lji5gHGZDUhgZoJR2h/pEyWk WF8431M2MVI7aPdCr9vtrysR7ZQF2JxFNEVlglrijjILMCiJBPsUXnakNYZ92/FJHP bhiEipmK+ZW8mDX4QpZYa0wfGQzhWirARb8yFE+k= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 4BCCD6063A Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=bgodavar@codeaurora.org From: Balakrishna Godavarthi To: marcel@holtmann.org, johan.hedberg@gmail.com, mka@chromium.org Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-bluetooth@vger.kernel.org, thierry.escande@linaro.org, rtatiya@codeaurora.org, hemantg@codeaurora.org, linux-arm-msm@vger.kernel.org, Balakrishna Godavarthi Subject: [PATCH v15 5/7] Bluetooth: hci_qca: Enable 3.2 Mbps operating speed. Date: Fri, 3 Aug 2018 17:46:30 +0530 Message-Id: <20180803121632.30689-6-bgodavar@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180803121632.30689-1-bgodavar@codeaurora.org> References: <20180803121632.30689-1-bgodavar@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Enable Qualcomm chips to operate at 3.2Mbps. Signed-off-by: Balakrishna Godavarthi Reviewed-by: Matthias Kaehlcke --- drivers/bluetooth/hci_qca.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 5f8a74d65bec..a6e7d38ef931 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -877,6 +877,8 @@ static uint8_t qca_get_baudrate_value(int speed) return QCA_BAUDRATE_2000000; case 3000000: return QCA_BAUDRATE_3000000; + case 3200000: + return QCA_BAUDRATE_3200000; case 3500000: return QCA_BAUDRATE_3500000; default: @@ -891,7 +893,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) struct sk_buff *skb; u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 }; - if (baudrate > QCA_BAUDRATE_3000000) + if (baudrate > QCA_BAUDRATE_3200000) return -EINVAL; cmd[4] = baudrate; From patchwork Fri Aug 3 12:16:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Balakrishna Godavarthi X-Patchwork-Id: 10555049 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 46A3313AC for ; Fri, 3 Aug 2018 12:17:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3B5462B8FF for ; Fri, 3 Aug 2018 12:17:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2FAA32B916; Fri, 3 Aug 2018 12:17:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C2D282B8FF for ; Fri, 3 Aug 2018 12:17:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731845AbeHCONM (ORCPT ); Fri, 3 Aug 2018 10:13:12 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:45570 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727403AbeHCONL (ORCPT ); Fri, 3 Aug 2018 10:13:11 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 045E96035F; Fri, 3 Aug 2018 12:17:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298627; bh=AG4B2NW23/TwoMGK86L9kgbiKZ7kdcNiIeEd0e/Hs14=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nQ+a1/SYE9/JgAoaiu8Bp7RtOPB7CeO2HMZGdlOYF/oVgGJpFKOG1fj9RF7ZRKDS8 bhX0ygrsI0LNm0ET0sM+UVFCrBAvtoIwIeAcXW1WNTu56G+ilBVzU1UYNn9XiOmSb0 cwztqt/3/znyOsqdJhnjr8BZ1NYPqx3Ogbb9YrwE= Received: from bgodavar-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: bgodavar@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 2E9BB60B73; Fri, 3 Aug 2018 12:17:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298625; bh=AG4B2NW23/TwoMGK86L9kgbiKZ7kdcNiIeEd0e/Hs14=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j9tDRJcy2ojUbyAgTLX3A9mY+wYN5AWP5ulAcwROMz1/4DigDv3pnAdvCaGAjkTFL YcfPdbSjInN4CnTFhxbhTA2+01USsXtJurZuDkNHixmUHl0QCktpuPGN2gotEpQB28 tBm0KnwRCyD+afByr5eul8VNj/E1mzvoD73nk+J8= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 2E9BB60B73 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=bgodavar@codeaurora.org From: Balakrishna Godavarthi To: marcel@holtmann.org, johan.hedberg@gmail.com, mka@chromium.org Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-bluetooth@vger.kernel.org, thierry.escande@linaro.org, rtatiya@codeaurora.org, hemantg@codeaurora.org, linux-arm-msm@vger.kernel.org, Balakrishna Godavarthi Subject: [PATCH v15 6/7] Bluetooth: btqca: Add wcn3990 firmware download support. Date: Fri, 3 Aug 2018 17:46:31 +0530 Message-Id: <20180803121632.30689-7-bgodavar@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180803121632.30689-1-bgodavar@codeaurora.org> References: <20180803121632.30689-1-bgodavar@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch enables the RAM and NV patch download for wcn3990. Signed-off-by: Balakrishna Godavarthi Reviewed-by: Matthias Kaehlcke --- drivers/bluetooth/btqca.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index 479179c54dcf..488f5e7521dd 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -336,6 +336,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, { struct rome_config config; int err; + u8 rom_ver; bt_dev_dbg(hdev, "QCA setup on UART"); @@ -343,8 +344,19 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, /* Download rampatch file */ config.type = TLV_TYPE_PATCH; - snprintf(config.fwname, sizeof(config.fwname), "qca/rampatch_%08x.bin", - soc_ver); + if (soc_type == QCA_WCN3990) { + /* Firmware files to download are based on ROM version. + * ROM version is derived from last two bytes of soc_ver. + */ + rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | + (soc_ver & 0x0000000f); + snprintf(config.fwname, sizeof(config.fwname), + "qca/crbtfw%02x.tlv", rom_ver); + } else { + snprintf(config.fwname, sizeof(config.fwname), + "qca/rampatch_%08x.bin", soc_ver); + } + err = qca_download_firmware(hdev, &config); if (err < 0) { bt_dev_err(hdev, "QCA Failed to download patch (%d)", err); @@ -353,8 +365,13 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, /* Download NVM configuration */ config.type = TLV_TYPE_NVM; - snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin", - soc_ver); + if (soc_type == QCA_WCN3990) + snprintf(config.fwname, sizeof(config.fwname), + "qca/crnv%02x.bin", rom_ver); + else + snprintf(config.fwname, sizeof(config.fwname), + "qca/nvm_%08x.bin", soc_ver); + err = qca_download_firmware(hdev, &config); if (err < 0) { bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err); From patchwork Fri Aug 3 12:16:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Balakrishna Godavarthi X-Patchwork-Id: 10555051 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1F03E13AC for ; Fri, 3 Aug 2018 12:17:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 10C1A2B90C for ; Fri, 3 Aug 2018 12:17:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 048C22B916; Fri, 3 Aug 2018 12:17:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BEBB42B984 for ; Fri, 3 Aug 2018 12:17:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727403AbeHCONT (ORCPT ); Fri, 3 Aug 2018 10:13:19 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:45728 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727148AbeHCONT (ORCPT ); Fri, 3 Aug 2018 10:13:19 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 963686063A; Fri, 3 Aug 2018 12:17:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298633; bh=byWZh3i76qtbZqwTfy+YHSPchIfz38t9UNqbttZAlyE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g5Kwz+wQZsJ7hOeIljXJcZvnYFLIh/1iEhZY8u/ezbTYMV2ARYvGQfWc2X6Do8wu3 6lMaQn6BNfzcsFaj0NGItTi66zQyLk1Kjlc42wxPg54YKyudCEWwtBP2iv18ABOXlt QTLtBv8Qk+3MyM6fCCbCsLy/CGH0hF+2mlFl0P7A= Received: from bgodavar-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: bgodavar@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 555D960AD8; Fri, 3 Aug 2018 12:17:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533298630; bh=byWZh3i76qtbZqwTfy+YHSPchIfz38t9UNqbttZAlyE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Fzo3r3aBZ5xqfHiGgo+JFxFBiOgrHoj2BRtNUjV2iy4MXTXbqihARjOxe7HQwyKai puTaG/HyHVrV8q5trshF1q/QdVhv5dwtDlXzc7sFH9aIghpCss41IE+26ejFIxr2TQ ZhpTJ2SloxhJ1jWXkaVH0U6sKz9Egliq0xEbmwX8= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 555D960AD8 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=bgodavar@codeaurora.org From: Balakrishna Godavarthi To: marcel@holtmann.org, johan.hedberg@gmail.com, mka@chromium.org Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-bluetooth@vger.kernel.org, thierry.escande@linaro.org, rtatiya@codeaurora.org, hemantg@codeaurora.org, linux-arm-msm@vger.kernel.org, Balakrishna Godavarthi Subject: [PATCH v15 7/7] Bluetooth: hci_qca: Add support for Qualcomm Bluetooth chip wcn3990 Date: Fri, 3 Aug 2018 17:46:32 +0530 Message-Id: <20180803121632.30689-8-bgodavar@codeaurora.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180803121632.30689-1-bgodavar@codeaurora.org> References: <20180803121632.30689-1-bgodavar@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add support to set voltage/current of various regulators to power up/down Bluetooth chip wcn3990. Signed-off-by: Balakrishna Godavarthi Reviewed-by: Matthias Kaehlcke --- Changes in v15: * addressed return ret to return 0 Changes in v14: * moved function call qca_read_soc_version() to qca_setup() Changes in v13: * updated review comments. Changes in v12: * removed retrying iteration loop in qca_wcn3990_init. Changes in v11: * removed support to read regulator currents from dts. * updated review comments. Changes in v10: * added support to read regulator currents from dts. * added support to try to connect with chip if it fails to respond to initial commands * updated review comments. changes in v9: * moved flow control to vendor and set_baudarte functions. * removed parent regs. changes in v8: * closing qca buffer, if qca_power_setup fails * chnaged ibs start timer function call location. * updated review comments. changes in v7: * addressed review comments. changes in v6: * Hooked up qca_power to qca_serdev. * renamed all the naming inconsistency functions with qca_* * leveraged common code of ROME for wcn3990. * created wrapper functions for re-usable blocks. * updated function of _*regulator_enable and _*regualtor_disable. * removed redundant comments and functions. * addressed review comments. Changes in v5: * updated regulator vddpa min_uV to 1304000. * addressed review comments. Changes in v4: * Segregated the changes of btqca from hci_qca * rebased all changes on top of bluetooth-next. * addressed review comments. --- drivers/bluetooth/btqca.h | 3 + drivers/bluetooth/hci_qca.c | 407 +++++++++++++++++++++++++++++++----- 2 files changed, 363 insertions(+), 47 deletions(-) diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index a9c2779f3e07..0c01f375fe83 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -37,6 +37,9 @@ #define EDL_TAG_ID_HCI (17) #define EDL_TAG_ID_DEEP_SLEEP (27) +#define QCA_WCN3990_POWERON_PULSE 0xFC +#define QCA_WCN3990_POWEROFF_PULSE 0xC0 + enum qca_bardrate { QCA_BAUDRATE_115200 = 0, QCA_BAUDRATE_57600, diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index a6e7d38ef931..d9aa4325ff2a 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -5,7 +5,7 @@ * protocol extension to H4. * * Copyright (C) 2007 Texas Instruments, Inc. - * Copyright (c) 2010, 2012 The Linux Foundation. All rights reserved. + * Copyright (c) 2010, 2012, 2018 The Linux Foundation. All rights reserved. * * Acknowledgements: * This file is based on hci_ll.c, which was... @@ -31,9 +31,14 @@ #include #include #include +#include +#include #include #include #include +#include +#include +#include #include #include @@ -124,12 +129,46 @@ enum qca_speed_type { QCA_OPER_SPEED }; +/* + * Voltage regulator information required for configuring the + * QCA Bluetooth chipset + */ +struct qca_vreg { + const char *name; + unsigned int min_uV; + unsigned int max_uV; + unsigned int load_uA; +}; + +struct qca_vreg_data { + enum qca_btsoc_type soc_type; + struct qca_vreg *vregs; + size_t num_vregs; +}; + +/* + * Platform data for the QCA Bluetooth power driver. + */ +struct qca_power { + struct device *dev; + const struct qca_vreg_data *vreg_data; + struct regulator_bulk_data *vreg_bulk; + bool vregs_on; +}; + struct qca_serdev { struct hci_uart serdev_hu; struct gpio_desc *bt_en; struct clk *susclk; + enum qca_btsoc_type btsoc_type; + struct qca_power *bt_power; + u32 init_speed; + u32 oper_speed; }; +static int qca_power_setup(struct hci_uart *hu, bool on); +static void qca_power_shutdown(struct hci_dev *hdev); + static void __serial_clock_on(struct tty_struct *tty) { /* TODO: Some chipset requires to enable UART clock on client @@ -407,6 +446,7 @@ static int qca_open(struct hci_uart *hu) { struct qca_serdev *qcadev; struct qca_data *qca; + int ret; BT_DBG("hu %p qca_open", hu); @@ -458,19 +498,32 @@ static int qca_open(struct hci_uart *hu) hu->priv = qca; - timer_setup(&qca->wake_retrans_timer, hci_ibs_wake_retrans_timeout, 0); - qca->wake_retrans = IBS_WAKE_RETRANS_TIMEOUT_MS; - - timer_setup(&qca->tx_idle_timer, hci_ibs_tx_idle_timeout, 0); - qca->tx_idle_delay = IBS_TX_IDLE_TIMEOUT_MS; - if (hu->serdev) { serdev_device_open(hu->serdev); qcadev = serdev_device_get_drvdata(hu->serdev); - gpiod_set_value_cansleep(qcadev->bt_en, 1); + if (qcadev->btsoc_type != QCA_WCN3990) { + gpiod_set_value_cansleep(qcadev->bt_en, 1); + } else { + hu->init_speed = qcadev->init_speed; + hu->oper_speed = qcadev->oper_speed; + ret = qca_power_setup(hu, true); + if (ret) { + destroy_workqueue(qca->workqueue); + kfree_skb(qca->rx_skb); + hu->priv = NULL; + kfree(qca); + return ret; + } + } } + timer_setup(&qca->wake_retrans_timer, hci_ibs_wake_retrans_timeout, 0); + qca->wake_retrans = IBS_WAKE_RETRANS_TIMEOUT_MS; + + timer_setup(&qca->tx_idle_timer, hci_ibs_tx_idle_timeout, 0); + qca->tx_idle_delay = IBS_TX_IDLE_TIMEOUT_MS; + BT_DBG("HCI_UART_QCA open, tx_idle_delay=%u, wake_retrans=%u", qca->tx_idle_delay, qca->wake_retrans); @@ -554,10 +607,13 @@ static int qca_close(struct hci_uart *hu) qca->hu = NULL; if (hu->serdev) { - serdev_device_close(hu->serdev); - qcadev = serdev_device_get_drvdata(hu->serdev); - gpiod_set_value_cansleep(qcadev->bt_en, 0); + if (qcadev->btsoc_type == QCA_WCN3990) + qca_power_shutdown(hu->hdev); + else + gpiod_set_value_cansleep(qcadev->bt_en, 0); + + serdev_device_close(hu->serdev); } kfree_skb(qca->rx_skb); @@ -891,6 +947,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) struct hci_uart *hu = hci_get_drvdata(hdev); struct qca_data *qca = hu->priv; struct sk_buff *skb; + struct qca_serdev *qcadev; u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 }; if (baudrate > QCA_BAUDRATE_3200000) @@ -904,6 +961,13 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) return -ENOMEM; } + /* Disabling hardware flow control is mandatory while + * sending change baudrate request to wcn3990 SoC. + */ + qcadev = serdev_device_get_drvdata(hu->serdev); + if (qcadev->btsoc_type == QCA_WCN3990) + hci_uart_set_flow_control(hu, true); + /* Assign commands to change baudrate and packet type. */ skb_put_data(skb, cmd, sizeof(cmd)); hci_skb_pkt_type(skb) = HCI_COMMAND_PKT; @@ -919,6 +983,9 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS)); set_current_state(TASK_RUNNING); + if (qcadev->btsoc_type == QCA_WCN3990) + hci_uart_set_flow_control(hu, false); + return 0; } @@ -930,6 +997,43 @@ static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed) hci_uart_set_baudrate(hu, speed); } +static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd) +{ + struct hci_uart *hu = hci_get_drvdata(hdev); + struct qca_data *qca = hu->priv; + struct sk_buff *skb; + + /* These power pulses are single byte command which are sent + * at required baudrate to wcn3990. On wcn3990, we have an external + * circuit at Tx pin which decodes the pulse sent at specific baudrate. + * For example, wcn3990 supports RF COEX antenna for both Wi-Fi/BT + * and also we use the same power inputs to turn on and off for + * Wi-Fi/BT. Powering up the power sources will not enable BT, until + * we send a power on pulse at 115200 bps. This algorithm will help to + * save power. Disabling hardware flow control is mandatory while + * sending power pulses to SoC. + */ + bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd); + + skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL); + if (!skb) + return -ENOMEM; + + hci_uart_set_flow_control(hu, true); + + skb_put_u8(skb, cmd); + hci_skb_pkt_type(skb) = HCI_COMMAND_PKT; + + skb_queue_tail(&qca->txq, skb); + hci_uart_tx_wakeup(hu); + + /* Wait for 100 uS for SoC to settle down */ + usleep_range(100, 200); + hci_uart_set_flow_control(hu, false); + + return 0; +} + static unsigned int qca_get_speed(struct hci_uart *hu, enum qca_speed_type speed_type) { @@ -952,9 +1056,18 @@ static unsigned int qca_get_speed(struct hci_uart *hu, static int qca_check_speeds(struct hci_uart *hu) { - if (!qca_get_speed(hu, QCA_INIT_SPEED) || - !qca_get_speed(hu, QCA_OPER_SPEED)) - return -EINVAL; + struct qca_serdev *qcadev; + + qcadev = serdev_device_get_drvdata(hu->serdev); + if (qcadev->btsoc_type == QCA_WCN3990) { + if (!qca_get_speed(hu, QCA_INIT_SPEED) && + !qca_get_speed(hu, QCA_OPER_SPEED)) + return -EINVAL; + } else { + if (!qca_get_speed(hu, QCA_INIT_SPEED) || + !qca_get_speed(hu, QCA_OPER_SPEED)) + return -EINVAL; + } return 0; } @@ -974,7 +1087,7 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) return 0; qca_baudrate = qca_get_baudrate_value(speed); - bt_dev_info(hu->hdev, "Set UART speed to %d", speed); + bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed); ret = qca_set_baudrate(hu->hdev, qca_baudrate); if (ret) return ret; @@ -985,15 +1098,52 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) return 0; } +static int qca_wcn3990_init(struct hci_uart *hu) +{ + struct hci_dev *hdev = hu->hdev; + int ret; + + /* Forcefully enable wcn3990 to enter in to boot mode. */ + host_set_baudrate(hu, 2400); + ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE); + if (ret) + return ret; + + qca_set_speed(hu, QCA_INIT_SPEED); + ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWERON_PULSE); + if (ret) + return ret; + + /* Wait for 100 ms for SoC to boot */ + msleep(100); + + /* Now the device is in ready state to communicate with host. + * To sync host with device we need to reopen port. + * Without this, we will have RTS and CTS synchronization + * issues. + */ + serdev_device_close(hu->serdev); + ret = serdev_device_open(hu->serdev); + if (ret) { + bt_dev_err(hu->hdev, "failed to open port"); + return ret; + } + + hci_uart_set_flow_control(hu, false); + + return 0; +} + static int qca_setup(struct hci_uart *hu) { struct hci_dev *hdev = hu->hdev; struct qca_data *qca = hu->priv; unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200; + struct qca_serdev *qcadev; int ret; int soc_ver = 0; - bt_dev_info(hdev, "ROME setup"); + qcadev = serdev_device_get_drvdata(hu->serdev); ret = qca_check_speeds(hu); if (ret) @@ -1002,8 +1152,19 @@ static int qca_setup(struct hci_uart *hu) /* Patch downloading has to be done without IBS mode */ clear_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags); - /* Setup initial baudrate */ - qca_set_speed(hu, QCA_INIT_SPEED); + if (qcadev->btsoc_type == QCA_WCN3990) { + bt_dev_info(hdev, "setting up wcn3990"); + ret = qca_wcn3990_init(hu); + if (ret) + return ret; + + ret = qca_read_soc_version(hdev, &soc_ver); + if (ret) + return ret; + } else { + bt_dev_info(hdev, "ROME setup"); + qca_set_speed(hu, QCA_INIT_SPEED); + } /* Setup user speed if needed */ speed = qca_get_speed(hu, QCA_OPER_SPEED); @@ -1015,15 +1176,16 @@ static int qca_setup(struct hci_uart *hu) qca_baudrate = qca_get_baudrate_value(speed); } - /* Get QCA version information */ - ret = qca_read_soc_version(hdev, &soc_ver); - if (ret) - return ret; + if (qcadev->btsoc_type != QCA_WCN3990) { + /* Get QCA version information */ + ret = qca_read_soc_version(hdev, &soc_ver); + if (ret) + return ret; + } bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver); - /* Setup patch / NVM configurations */ - ret = qca_uart_setup(hdev, qca_baudrate, QCA_ROME, soc_ver); + ret = qca_uart_setup(hdev, qca_baudrate, qcadev->btsoc_type, soc_ver); if (!ret) { set_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags); qca_debugfs_init(hdev); @@ -1059,9 +1221,123 @@ static struct hci_uart_proto qca_proto = { .dequeue = qca_dequeue, }; +static const struct qca_vreg_data qca_soc_data = { + .soc_type = QCA_WCN3990, + .vregs = (struct qca_vreg []) { + { "vddio", 1800000, 1900000, 15000 }, + { "vddxo", 1800000, 1900000, 80000 }, + { "vddrf", 1300000, 1350000, 300000 }, + { "vddch0", 3300000, 3400000, 450000 }, + }, + .num_vregs = 4, +}; + +static void qca_power_shutdown(struct hci_dev *hdev) +{ + struct hci_uart *hu = hci_get_drvdata(hdev); + + host_set_baudrate(hu, 2400); + qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE); + qca_power_setup(hu, false); +} + +static int qca_enable_regulator(struct qca_vreg vregs, + struct regulator *regulator) +{ + int ret; + + ret = regulator_set_voltage(regulator, vregs.min_uV, + vregs.max_uV); + if (ret) + return ret; + + if (vregs.load_uA) + ret = regulator_set_load(regulator, + vregs.load_uA); + + if (ret) + return ret; + + return regulator_enable(regulator); + +} + +static void qca_disable_regulator(struct qca_vreg vregs, + struct regulator *regulator) +{ + regulator_disable(regulator); + regulator_set_voltage(regulator, 0, vregs.max_uV); + if (vregs.load_uA) + regulator_set_load(regulator, 0); + +} + +static int qca_power_setup(struct hci_uart *hu, bool on) +{ + struct qca_vreg *vregs; + struct regulator_bulk_data *vreg_bulk; + struct qca_serdev *qcadev; + int i, num_vregs, ret = 0; + + qcadev = serdev_device_get_drvdata(hu->serdev); + if (!qcadev || !qcadev->bt_power || !qcadev->bt_power->vreg_data || + !qcadev->bt_power->vreg_bulk) + return -EINVAL; + + vregs = qcadev->bt_power->vreg_data->vregs; + vreg_bulk = qcadev->bt_power->vreg_bulk; + num_vregs = qcadev->bt_power->vreg_data->num_vregs; + BT_DBG("on: %d", on); + if (on && !qcadev->bt_power->vregs_on) { + for (i = 0; i < num_vregs; i++) { + ret = qca_enable_regulator(vregs[i], + vreg_bulk[i].consumer); + if (ret) + break; + } + + if (ret) { + BT_ERR("failed to enable regulator:%s", vregs[i].name); + /* turn off regulators which are enabled */ + for (i = i - 1; i >= 0; i--) + qca_disable_regulator(vregs[i], + vreg_bulk[i].consumer); + } else { + qcadev->bt_power->vregs_on = true; + } + } else if (!on && qcadev->bt_power->vregs_on) { + /* turn off regulator in reverse order */ + i = qcadev->bt_power->vreg_data->num_vregs - 1; + for ( ; i >= 0; i--) + qca_disable_regulator(vregs[i], vreg_bulk[i].consumer); + + qcadev->bt_power->vregs_on = false; + } + + return ret; +} + +static int qca_init_regulators(struct qca_power *qca, + const struct qca_vreg *vregs, size_t num_vregs) +{ + int i; + + qca->vreg_bulk = devm_kzalloc(qca->dev, num_vregs * + sizeof(struct regulator_bulk_data), + GFP_KERNEL); + if (!qca->vreg_bulk) + return -ENOMEM; + + for (i = 0; i < num_vregs; i++) + qca->vreg_bulk[i].supply = vregs[i].name; + + return devm_regulator_bulk_get(qca->dev, num_vregs, qca->vreg_bulk); +} + static int qca_serdev_probe(struct serdev_device *serdev) { struct qca_serdev *qcadev; + const struct qca_vreg_data *data; int err; qcadev = devm_kzalloc(&serdev->dev, sizeof(*qcadev), GFP_KERNEL); @@ -1069,47 +1345,84 @@ static int qca_serdev_probe(struct serdev_device *serdev) return -ENOMEM; qcadev->serdev_hu.serdev = serdev; + data = of_device_get_match_data(&serdev->dev); serdev_device_set_drvdata(serdev, qcadev); + if (data && data->soc_type == QCA_WCN3990) { + qcadev->btsoc_type = QCA_WCN3990; + qcadev->bt_power = devm_kzalloc(&serdev->dev, + sizeof(struct qca_power), + GFP_KERNEL); + if (!qcadev->bt_power) + return -ENOMEM; + + qcadev->bt_power->dev = &serdev->dev; + qcadev->bt_power->vreg_data = data; + err = qca_init_regulators(qcadev->bt_power, data->vregs, + data->num_vregs); + if (err) { + BT_ERR("Failed to init regulators:%d", err); + goto out; + } - qcadev->bt_en = devm_gpiod_get(&serdev->dev, "enable", - GPIOD_OUT_LOW); - if (IS_ERR(qcadev->bt_en)) { - dev_err(&serdev->dev, "failed to acquire enable gpio\n"); - return PTR_ERR(qcadev->bt_en); - } + qcadev->bt_power->vregs_on = false; - qcadev->susclk = devm_clk_get(&serdev->dev, NULL); - if (IS_ERR(qcadev->susclk)) { - dev_err(&serdev->dev, "failed to acquire clk\n"); - return PTR_ERR(qcadev->susclk); - } + device_property_read_u32(&serdev->dev, "max-speed", + &qcadev->oper_speed); + if (!qcadev->oper_speed) + BT_DBG("UART will pick default operating speed"); - err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ); - if (err) - return err; + err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto); + if (err) { + BT_ERR("wcn3990 serdev registration failed"); + goto out; + } + } else { + qcadev->btsoc_type = QCA_ROME; + qcadev->bt_en = devm_gpiod_get(&serdev->dev, "enable", + GPIOD_OUT_LOW); + if (IS_ERR(qcadev->bt_en)) { + dev_err(&serdev->dev, "failed to acquire enable gpio\n"); + return PTR_ERR(qcadev->bt_en); + } - err = clk_prepare_enable(qcadev->susclk); - if (err) - return err; + qcadev->susclk = devm_clk_get(&serdev->dev, NULL); + if (IS_ERR(qcadev->susclk)) { + dev_err(&serdev->dev, "failed to acquire clk\n"); + return PTR_ERR(qcadev->susclk); + } - err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto); - if (err) - clk_disable_unprepare(qcadev->susclk); + err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ); + if (err) + return err; + + err = clk_prepare_enable(qcadev->susclk); + if (err) + return err; + + err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto); + if (err) + clk_disable_unprepare(qcadev->susclk); + } + +out: return err; - return err; } static void qca_serdev_remove(struct serdev_device *serdev) { struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); - hci_uart_unregister_device(&qcadev->serdev_hu); + if (qcadev->btsoc_type == QCA_WCN3990) + qca_power_shutdown(qcadev->serdev_hu.hdev); + else + clk_disable_unprepare(qcadev->susclk); - clk_disable_unprepare(qcadev->susclk); + hci_uart_unregister_device(&qcadev->serdev_hu); } static const struct of_device_id qca_bluetooth_of_match[] = { { .compatible = "qcom,qca6174-bt" }, + { .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data}, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);