Received: by 2002:ab2:6857:0:b0:1ef:ffd0:ce49 with SMTP id l23csp2530316lqp; Mon, 25 Mar 2024 01:19:02 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWmc6HlbFTbYucfSNepkFCtCn7dRKuh4l7q2zP14bDjHyYuaP0lFOS63+kgR0tiIgJ9ndhATyTZM0nXex2KK2lxvvAVdQLgFwHr0SQLmA== X-Google-Smtp-Source: AGHT+IHL09MpZ0qfzkw/0pgZ/TCKhK1wkPfP1obtndGmdOxNqkOFm4gsopbqrqQq6p89tEcgHM5/ X-Received: by 2002:a50:c04c:0:b0:565:7b61:4c82 with SMTP id u12-20020a50c04c000000b005657b614c82mr3751515edd.5.1711354741782; Mon, 25 Mar 2024 01:19:01 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1711354741; cv=pass; d=google.com; s=arc-20160816; b=xNMtx4WtXg+aAM4CYyxRrlk1Un9TKKhL74cOCtS6tcX2Xp80rMFq5zLLXTrjAIKdK/ B4w39KolaU2PWk0huuK7gqux9thzpZJnWbjTC1s7BYcB0/KGpRNuNMjjymWJQU3gIzO3 2fEnxyXBYefDgB/pk4AGU4OB1W9K5e2+rcz+6nj2PbOs7tJZCOGX6/8GqkrxfAUT4hsN P5fqhrAHH1BU5eJsjsUhECV6/J1WaCBRG+O1mqa/TVZ6Z/P8bxyQ2blxvPm8TFCe/Q4y xlcH+dzXWRyKMtg3QIogzQ1E43Xy2CEvtU32AhPIE7ZfkQItCvnKaLKxkzMixcZdUxIx kgSg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=a3QkifLO0rcH47t6QH9lLDavUFjG1SH0ES6tf7wj0os=; fh=1ZyFSgYrfRCdrf1KxNDzIGrsQDpixEhZ6leTh/WF+jQ=; b=clb35+WmbpFp2T/wJdybVPTiLk2i4YG+jeT1a7acG+atQWCK142XLuHvc7xnOA5tcp sD4wCKY3nGqIAqw8U/sGd5FGzOLh/CvYjQmk3yRUQc2L691b5I9lhIejrRmEOowduDHk 8Onht0oaPl2k7JszMb+t2YfmIZFboUXm9E/f3ZsEYiZQOiYVstjLBd5pGugsXEwUQNrR 0LDwtWjH6xlP4qRbn1d6PcmdyRr0YB052h1UiG7SEXxpIyKPwfDnVrBTiRE89+1AGdgk U/XJLOwhtFZAKthpsu2VJ7UOwANnBNFQboTZkMfMt2ShoEtGDEEEyxfUVHJA072ZHlDj Fk4A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="i2WN/Een"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-116040-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-116040-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id h3-20020a0564020e8300b0056c06e3884bsi1311181eda.180.2024.03.25.01.19.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Mar 2024 01:19:01 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-116040-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="i2WN/Een"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-116040-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-116040-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 58FF91F30486 for ; Mon, 25 Mar 2024 08:19:01 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0A3E82720E7; Mon, 25 Mar 2024 03:28:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="i2WN/Een" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 59934176522; Sun, 24 Mar 2024 23:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711323428; cv=none; b=dYsa0SfsfSz1ebjikeRTUnp++DgSii/2mnwa3TyXAoHn6DBt2Jlo6Xg6cmvQxcXiiJaiw+1S/gdgUUWPVnJPag8BNPkSAmx6+MmvHmeC1IlNX/NqiYVQsn6hZ8lDILHf8PI4T6OQRYnRHmCN/98JSnpz6vYg48thbvMaw3ZO/QM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711323428; c=relaxed/simple; bh=SYIICNQzH4OBpBs/3NMFn9Ma5aGTMNM/qlRXoJvI51U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=egRhSCSC7ER3hwvNLyyDY0nFernWZdguE1WUmZj84XykxFIMa0fXnPezCxky7UqNpUQoL3xoK6zjrc9HqroLSkWwedTKczRcmIfx/unwAt4xixBVDz7QYYtn1QvSJh7B47yUT0uqLHElEraVVwfOB5CkyUDhDTuEOgzlXD6FLUQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=i2WN/Een; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8000BC43399; Sun, 24 Mar 2024 23:37:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1711323427; bh=SYIICNQzH4OBpBs/3NMFn9Ma5aGTMNM/qlRXoJvI51U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i2WN/EenbSqHTqf2m6HBcRYigcytx2afS6SeZHiNCjhYdN4iPNoGYRkd0xxug409Q dnDOKyZNxMOIhJD1rT5oip0lGT1k/I03KAq2RGf7KOHiCe0/VRSEQwbaybjWZAv8UC npwdGB6Ex9LksXvVmQxBlqwihkyph18t7dZjzF3xg1NiVi1tr7NYHgtzkjJKrASgSy Z+jgOMJB0rjzMDXl6efjMSFIxlyYrmNdJ9lT6d3dRjQ30JPmaCGwh7u6qxETJPL6MV Aeo7julk6FfR2hrC9HLZIdQOZTk/25D/cKcQgrtNVYiauCVNjQlcMKofN6XwoXIhKN ypFpkoFFNv42w== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Steev Klimaszewski , Bjorn Andersson , Luiz Augusto von Dentz , Sasha Levin Subject: [PATCH 5.15 129/317] Bluetooth: hci_qca: Add support for QTI Bluetooth chip wcn6855 Date: Sun, 24 Mar 2024 19:31:49 -0400 Message-ID: <20240324233458.1352854-130-sashal@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240324233458.1352854-1-sashal@kernel.org> References: <20240324233458.1352854-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit From: Steev Klimaszewski [ Upstream commit 095327fede005f4b14d40b2183b2f7965c739dbd ] Add regulators, GPIOs and changes required to power on/off wcn6855. Add support for firmware download for wcn6855 which is in the linux-firmware repository as hpbtfw21.tlv and hpnv21.bin. Based on the assumption that this is similar to the wcn6750 Tested-on: BTFW.HSP.2.1.0-00538-VER_PATCHZ-1 Signed-off-by: Steev Klimaszewski Reviewed-by: Bjorn Andersson Tested-by: Bjorn Andersson Signed-off-by: Luiz Augusto von Dentz Stable-dep-of: 56d074d26c58 ("Bluetooth: hci_qca: don't use IS_ERR_OR_NULL() with gpiod_get_optional()") Signed-off-by: Sasha Levin --- drivers/bluetooth/btqca.c | 14 ++++++++- drivers/bluetooth/btqca.h | 10 +++++++ drivers/bluetooth/hci_qca.c | 57 ++++++++++++++++++++++++++++--------- 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index be04d74037d20..0f3943ac54179 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -566,6 +566,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, config.type = ELF_TYPE_PATCH; snprintf(config.fwname, sizeof(config.fwname), "qca/msbtfw%02x.mbn", rom_ver); + } else if (soc_type == QCA_WCN6855) { + snprintf(config.fwname, sizeof(config.fwname), + "qca/hpbtfw%02x.tlv", rom_ver); } else { snprintf(config.fwname, sizeof(config.fwname), "qca/rampatch_%08x.bin", soc_ver); @@ -600,6 +603,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, else if (soc_type == QCA_WCN6750) snprintf(config.fwname, sizeof(config.fwname), "qca/msnv%02x.bin", rom_ver); + else if (soc_type == QCA_WCN6855) + snprintf(config.fwname, sizeof(config.fwname), + "qca/hpnv%02x.bin", rom_ver); else snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin", soc_ver); @@ -637,11 +643,17 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate, return err; } - if (soc_type == QCA_WCN3991 || soc_type == QCA_WCN6750) { + switch (soc_type) { + case QCA_WCN3991: + case QCA_WCN6750: + case QCA_WCN6855: /* get fw build info */ err = qca_read_fw_build_info(hdev); if (err < 0) return err; + break; + default: + break; } bt_dev_info(hdev, "QCA setup on UART is completed"); diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h index 30afa7703afd3..b83bf202ea604 100644 --- a/drivers/bluetooth/btqca.h +++ b/drivers/bluetooth/btqca.h @@ -145,6 +145,7 @@ enum qca_btsoc_type { QCA_WCN3991, QCA_QCA6390, QCA_WCN6750, + QCA_WCN6855, }; #if IS_ENABLED(CONFIG_BT_QCA) @@ -166,6 +167,10 @@ static inline bool qca_is_wcn6750(enum qca_btsoc_type soc_type) { return soc_type == QCA_WCN6750; } +static inline bool qca_is_wcn6855(enum qca_btsoc_type soc_type) +{ + return soc_type == QCA_WCN6855; +} #else @@ -204,6 +209,11 @@ static inline bool qca_is_wcn6750(enum qca_btsoc_type soc_type) return false; } +static inline bool qca_is_wcn6855(enum qca_btsoc_type soc_type) +{ + return false; +} + static inline int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) { return -EOPNOTSUPP; diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index d10f1fe0f5fa8..7c641cabea7c8 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1315,7 +1315,8 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) /* Give the controller time to process the request */ if (qca_is_wcn399x(qca_soc_type(hu)) || - qca_is_wcn6750(qca_soc_type(hu))) + qca_is_wcn6750(qca_soc_type(hu)) || + qca_is_wcn6855(qca_soc_type(hu))) usleep_range(1000, 10000); else msleep(300); @@ -1392,7 +1393,8 @@ static unsigned int qca_get_speed(struct hci_uart *hu, static int qca_check_speeds(struct hci_uart *hu) { if (qca_is_wcn399x(qca_soc_type(hu)) || - qca_is_wcn6750(qca_soc_type(hu))) { + qca_is_wcn6750(qca_soc_type(hu)) || + qca_is_wcn6855(qca_soc_type(hu))) { if (!qca_get_speed(hu, QCA_INIT_SPEED) && !qca_get_speed(hu, QCA_OPER_SPEED)) return -EINVAL; @@ -1426,7 +1428,8 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) * changing the baudrate of chip and host. */ if (qca_is_wcn399x(soc_type) || - qca_is_wcn6750(soc_type)) + qca_is_wcn6750(soc_type) || + qca_is_wcn6855(soc_type)) hci_uart_set_flow_control(hu, true); if (soc_type == QCA_WCN3990) { @@ -1444,7 +1447,8 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type) error: if (qca_is_wcn399x(soc_type) || - qca_is_wcn6750(soc_type)) + qca_is_wcn6750(soc_type) || + qca_is_wcn6855(soc_type)) hci_uart_set_flow_control(hu, false); if (soc_type == QCA_WCN3990) { @@ -1680,7 +1684,8 @@ static int qca_power_on(struct hci_dev *hdev) return 0; if (qca_is_wcn399x(soc_type) || - qca_is_wcn6750(soc_type)) { + qca_is_wcn6750(soc_type) || + qca_is_wcn6855(soc_type)) { ret = qca_regulator_init(hu); } else { qcadev = serdev_device_get_drvdata(hu->serdev); @@ -1721,7 +1726,8 @@ static int qca_setup(struct hci_uart *hu) bt_dev_info(hdev, "setting up %s", qca_is_wcn399x(soc_type) ? "wcn399x" : - (soc_type == QCA_WCN6750) ? "wcn6750" : "ROME/QCA6390"); + (soc_type == QCA_WCN6750) ? "wcn6750" : + (soc_type == QCA_WCN6855) ? "wcn6855" : "ROME/QCA6390"); qca->memdump_state = QCA_MEMDUMP_IDLE; @@ -1733,7 +1739,8 @@ static int qca_setup(struct hci_uart *hu) clear_bit(QCA_SSR_TRIGGERED, &qca->flags); if (qca_is_wcn399x(soc_type) || - qca_is_wcn6750(soc_type)) { + qca_is_wcn6750(soc_type) || + qca_is_wcn6855(soc_type)) { set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); ret = qca_read_soc_version(hdev, &ver, soc_type); @@ -1754,7 +1761,8 @@ static int qca_setup(struct hci_uart *hu) } if (!(qca_is_wcn399x(soc_type) || - qca_is_wcn6750(soc_type))) { + qca_is_wcn6750(soc_type) || + qca_is_wcn6855(soc_type))) { /* Get QCA version information */ ret = qca_read_soc_version(hdev, &ver, soc_type); if (ret) @@ -1880,6 +1888,20 @@ static const struct qca_device_data qca_soc_data_wcn6750 = { .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, }; +static const struct qca_device_data qca_soc_data_wcn6855 = { + .soc_type = QCA_WCN6855, + .vregs = (struct qca_vreg []) { + { "vddio", 5000 }, + { "vddbtcxmx", 126000 }, + { "vddrfacmn", 12500 }, + { "vddrfa0p8", 102000 }, + { "vddrfa1p7", 302000 }, + { "vddrfa1p2", 257000 }, + }, + .num_vregs = 6, + .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, +}; + static void qca_power_shutdown(struct hci_uart *hu) { struct qca_serdev *qcadev; @@ -1909,7 +1931,7 @@ static void qca_power_shutdown(struct hci_uart *hu) host_set_baudrate(hu, 2400); qca_send_power_pulse(hu, false); qca_regulator_disable(qcadev); - } else if (soc_type == QCA_WCN6750) { + } else if (soc_type == QCA_WCN6750 || soc_type == QCA_WCN6855) { gpiod_set_value_cansleep(qcadev->bt_en, 0); msleep(100); qca_regulator_disable(qcadev); @@ -2044,7 +2066,8 @@ static int qca_serdev_probe(struct serdev_device *serdev) if (data && (qca_is_wcn399x(data->soc_type) || - qca_is_wcn6750(data->soc_type))) { + qca_is_wcn6750(data->soc_type) || + qca_is_wcn6855(data->soc_type))) { qcadev->btsoc_type = data->soc_type; qcadev->bt_power = devm_kzalloc(&serdev->dev, sizeof(struct qca_power), @@ -2064,14 +2087,18 @@ static int qca_serdev_probe(struct serdev_device *serdev) qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR_OR_NULL(qcadev->bt_en) && data->soc_type == QCA_WCN6750) { + if (IS_ERR_OR_NULL(qcadev->bt_en) && + (data->soc_type == QCA_WCN6750 || + data->soc_type == QCA_WCN6855)) { dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n"); power_ctrl_enabled = false; } qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl", GPIOD_IN); - if (IS_ERR_OR_NULL(qcadev->sw_ctrl) && data->soc_type == QCA_WCN6750) + if (IS_ERR_OR_NULL(qcadev->sw_ctrl) && + (data->soc_type == QCA_WCN6750 || + data->soc_type == QCA_WCN6855)) dev_warn(&serdev->dev, "failed to acquire SW_CTRL gpio\n"); qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL); @@ -2147,8 +2174,9 @@ static void qca_serdev_remove(struct serdev_device *serdev) struct qca_power *power = qcadev->bt_power; if ((qca_is_wcn399x(qcadev->btsoc_type) || - qca_is_wcn6750(qcadev->btsoc_type)) && - power->vregs_on) + qca_is_wcn6750(qcadev->btsoc_type) || + qca_is_wcn6855(qcadev->btsoc_type)) && + power->vregs_on) qca_power_shutdown(&qcadev->serdev_hu); else if (qcadev->susclk) clk_disable_unprepare(qcadev->susclk); @@ -2332,6 +2360,7 @@ static const struct of_device_id qca_bluetooth_of_match[] = { { .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991}, { .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998}, { .compatible = "qcom,wcn6750-bt", .data = &qca_soc_data_wcn6750}, + { .compatible = "qcom,wcn6855-bt", .data = &qca_soc_data_wcn6855}, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match); -- 2.43.0