diff mbox series

[v6,1/2] Bluetooth: hci_qca: Added support for WCN3998

Message ID 1553689723-21017-2-git-send-email-c-hbandi@codeaurora.org (mailing list archive)
State Superseded
Headers show
Series Enable Bluetooth functionality for WCN3998. | expand

Commit Message

Harish Bandi March 27, 2019, 12:28 p.m. UTC
Added new compatible for WCN3998 and corresponding voltage
and current values to WCN3998 compatible.
Changed driver code to support WCN3998

Signed-off-by: Harish Bandi <c-hbandi@codeaurora.org>
---
Changes in V6:
- changed return value to false in the qca_is_wcn399x()stub
---
 drivers/bluetooth/btqca.c   | 13 +++++++++++--
 drivers/bluetooth/btqca.h   |  8 +++++++-
 drivers/bluetooth/hci_qca.c | 40 ++++++++++++++++++++++++++--------------
 3 files changed, 44 insertions(+), 17 deletions(-)

Comments

Balakrishna Godavarthi March 27, 2019, 4:46 p.m. UTC | #1
Hi Harish,

On 2019-03-27 17:58, Harish Bandi wrote:
> Added new compatible for WCN3998 and corresponding voltage
> and current values to WCN3998 compatible.
> Changed driver code to support WCN3998
> 
> Signed-off-by: Harish Bandi <c-hbandi@codeaurora.org>
> ---
> Changes in V6:
> - changed return value to false in the qca_is_wcn399x()stub
> ---
>  drivers/bluetooth/btqca.c   | 13 +++++++++++--
>  drivers/bluetooth/btqca.h   |  8 +++++++-
>  drivers/bluetooth/hci_qca.c | 40 
> ++++++++++++++++++++++++++--------------
>  3 files changed, 44 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
> index 6122685..383e99f 100644
> --- a/drivers/bluetooth/btqca.c
> +++ b/drivers/bluetooth/btqca.c
> @@ -344,7 +344,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t 
> baudrate,
> 
>  	/* Download rampatch file */
>  	config.type = TLV_TYPE_PATCH;
> -	if (soc_type == QCA_WCN3990) {
> +	if (qca_is_wcn399x(soc_type)) {
>  		/* Firmware files to download are based on ROM version.
>  		 * ROM version is derived from last two bytes of soc_ver.
>  		 */
> @@ -365,7 +365,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t 
> baudrate,
> 
>  	/* Download NVM configuration */
>  	config.type = TLV_TYPE_NVM;
> -	if (soc_type == QCA_WCN3990)
> +	if (qca_is_wcn399x(soc_type))
>  		snprintf(config.fwname, sizeof(config.fwname),
>  			 "qca/crnv%02x.bin", rom_ver);
>  	else
> @@ -410,6 +410,15 @@ int qca_set_bdaddr(struct hci_dev *hdev, const
> bdaddr_t *bdaddr)
>  }
>  EXPORT_SYMBOL_GPL(qca_set_bdaddr);
> 
> +bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
> +{
> +	if ((soc_type == QCA_WCN3990) || (soc_type == QCA_WCN3998))
> +		return true;
> +
> +	return false;
> +}
> +EXPORT_SYMBOL_GPL(qca_is_wcn399x);
> +
>  MODULE_AUTHOR("Ben Young Tae Kim <ytkim@qca.qualcomm.com>");
>  MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver
> " VERSION);
>  MODULE_VERSION(VERSION);
> diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
> index 6fdc25d..0f68c9e7 100644
> --- a/drivers/bluetooth/btqca.h
> +++ b/drivers/bluetooth/btqca.h
> @@ -132,7 +132,8 @@ enum qca_btsoc_type {
>  	QCA_INVALID = -1,
>  	QCA_AR3002,
>  	QCA_ROME,
> -	QCA_WCN3990
> +	QCA_WCN3990,
> +	QCA_WCN3998,
>  };
> 
>  #if IS_ENABLED(CONFIG_BT_QCA)
> @@ -142,6 +143,7 @@ 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);
>  int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
> +bool qca_is_wcn399x(enum qca_btsoc_type soc_type);
>  #else
> 
>  static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const
> bdaddr_t *bdaddr)
> @@ -165,4 +167,8 @@ static inline int qca_set_bdaddr(struct hci_dev
> *hdev, const bdaddr_t *bdaddr)
>  	return -EOPNOTSUPP;
>  }
> 
> +static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
> +{
> +	return false;
> +}
>  #endif
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index 4ea995d..4af580a 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -521,7 +521,7 @@ static int qca_open(struct hci_uart *hu)
>  	if (hu->serdev) {
> 
>  		qcadev = serdev_device_get_drvdata(hu->serdev);
> -		if (qcadev->btsoc_type != QCA_WCN3990) {
> +		if (!qca_is_wcn399x(qcadev->btsoc_type)) {
>  			gpiod_set_value_cansleep(qcadev->bt_en, 1);
>  		} else {
>  			hu->init_speed = qcadev->init_speed;
> @@ -627,7 +627,7 @@ static int qca_close(struct hci_uart *hu)
> 
>  	if (hu->serdev) {
>  		qcadev = serdev_device_get_drvdata(hu->serdev);
> -		if (qcadev->btsoc_type == QCA_WCN3990)
> +		if (qca_is_wcn399x(qcadev->btsoc_type))
>  			qca_power_shutdown(hu);
>  		else
>  			gpiod_set_value_cansleep(qcadev->bt_en, 0);
> @@ -1008,7 +1008,7 @@ static int qca_set_baudrate(struct hci_dev
> *hdev, uint8_t baudrate)
>  		      msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
> 
>  	/* Give the controller time to process the request */
> -	if (qca_soc_type(hu) == QCA_WCN3990)
> +	if (qca_is_wcn399x(qca_soc_type(hu)))
>  		msleep(10);
>  	else
>  		msleep(300);
> @@ -1084,7 +1084,7 @@ static unsigned int qca_get_speed(struct hci_uart 
> *hu,
> 
>  static int qca_check_speeds(struct hci_uart *hu)
>  {
> -	if (qca_soc_type(hu) == QCA_WCN3990) {
> +	if (qca_is_wcn399x(qca_soc_type(hu))) {
>  		if (!qca_get_speed(hu, QCA_INIT_SPEED) &&
>  		    !qca_get_speed(hu, QCA_OPER_SPEED))
>  			return -EINVAL;
> @@ -1116,7 +1116,7 @@ static int qca_set_speed(struct hci_uart *hu,
> enum qca_speed_type speed_type)
>  		/* Disable flow control for wcn3990 to deassert RTS while
>  		 * changing the baudrate of chip and host.
>  		 */
> -		if (soc_type == QCA_WCN3990)
> +		if (qca_is_wcn399x(soc_type))
>  			hci_uart_set_flow_control(hu, true);
> 
>  		qca_baudrate = qca_get_baudrate_value(speed);
> @@ -1128,7 +1128,7 @@ static int qca_set_speed(struct hci_uart *hu,
> enum qca_speed_type speed_type)
>  		host_set_baudrate(hu, speed);
> 
>  error:
> -		if (soc_type == QCA_WCN3990)
> +		if (qca_is_wcn399x(soc_type))
>  			hci_uart_set_flow_control(hu, false);
>  	}
> 
> @@ -1201,7 +1201,7 @@ 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);
> 
> -	if (soc_type == QCA_WCN3990) {
> +	if (qca_is_wcn399x(soc_type)) {
>  		bt_dev_info(hdev, "setting up wcn3990");

[Bala]: nit: if you respin the serie.
              let us make this "wcn3990" string in the info message as 
wcn399x or with actual chip name.

> 
>  		/* Enable NON_PERSISTENT_SETUP QUIRK to ensure to execute
> @@ -1232,7 +1232,7 @@ static int qca_setup(struct hci_uart *hu)
>  		qca_baudrate = qca_get_baudrate_value(speed);
>  	}
> 
> -	if (soc_type != QCA_WCN3990) {
> +	if (!qca_is_wcn399x(soc_type)) {
>  		/* Get QCA version information */
>  		ret = qca_read_soc_version(hdev, &soc_ver);
>  		if (ret)
> @@ -1257,7 +1257,7 @@ static int qca_setup(struct hci_uart *hu)
>  	}
> 
>  	/* Setup bdaddr */
> -	if (soc_type == QCA_WCN3990)
> +	if (qca_is_wcn399x(soc_type))
>  		hu->hdev->set_bdaddr = qca_set_bdaddr;
>  	else
>  		hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
> @@ -1280,7 +1280,7 @@ static int qca_setup(struct hci_uart *hu)
>  	.dequeue	= qca_dequeue,
>  };
> 
> -static const struct qca_vreg_data qca_soc_data = {
> +static const struct qca_vreg_data qca_soc_data_wcn3990 = {
>  	.soc_type = QCA_WCN3990,
>  	.vregs = (struct qca_vreg []) {
>  		{ "vddio",   1800000, 1900000,  15000  },
> @@ -1291,6 +1291,17 @@ static int qca_setup(struct hci_uart *hu)
>  	.num_vregs = 4,
>  };
> 
> +static const struct qca_vreg_data qca_soc_data_wcn3998 = {
> +	.soc_type = QCA_WCN3998,
> +	.vregs = (struct qca_vreg []) {
> +		{ "vddio",   1800000, 1900000,  10000  },
> +		{ "vddxo",   1800000, 1900000,  80000  },
> +		{ "vddrf",   1300000, 1352000,  300000 },
> +		{ "vddch0",  3300000, 3300000,  450000 },
> +	},
> +	.num_vregs = 4,
> +};
> +
>  static void qca_power_shutdown(struct hci_uart *hu)
>  {
>  	struct qca_data *qca = hu->priv;
> @@ -1424,8 +1435,8 @@ static int qca_serdev_probe(struct serdev_device 
> *serdev)
>  	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;
> +	if (data && qca_is_wcn399x(data->soc_type)) {
> +		qcadev->btsoc_type = data->soc_type;
>  		qcadev->bt_power = devm_kzalloc(&serdev->dev,
>  						sizeof(struct qca_power),
>  						GFP_KERNEL);
> @@ -1489,7 +1500,7 @@ static void qca_serdev_remove(struct
> serdev_device *serdev)
>  {
>  	struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
> 
> -	if (qcadev->btsoc_type == QCA_WCN3990)
> +	if (qca_is_wcn399x(qcadev->btsoc_type))
>  		qca_power_shutdown(&qcadev->serdev_hu);
>  	else
>  		clk_disable_unprepare(qcadev->susclk);
> @@ -1499,7 +1510,8 @@ static void qca_serdev_remove(struct
> serdev_device *serdev)
> 
>  static const struct of_device_id qca_bluetooth_of_match[] = {
>  	{ .compatible = "qcom,qca6174-bt" },
> -	{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data},
> +	{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990},
> +	{ .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998},
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);

Reviewed-by: Balakrishna Godavarthi <bgodavar@codeaurora.org>
Matthias Kaehlcke March 27, 2019, 4:56 p.m. UTC | #2
On Wed, Mar 27, 2019 at 05:58:42PM +0530, Harish Bandi wrote:
> Added new compatible for WCN3998 and corresponding voltage
> and current values to WCN3998 compatible.
> Changed driver code to support WCN3998
> 
> Signed-off-by: Harish Bandi <c-hbandi@codeaurora.org>

You forgot to add 'Reviewed-by' my tag from v5. No need to resend,
I'll add it again below, but it's the general practice to include tags
like 'Reviewed-by' or 'Acked-by' when sending a new revision.

> ---
> Changes in V6:
> - changed return value to false in the qca_is_wcn399x()stub
> ---
>  drivers/bluetooth/btqca.c   | 13 +++++++++++--
>  drivers/bluetooth/btqca.h   |  8 +++++++-
>  drivers/bluetooth/hci_qca.c | 40 ++++++++++++++++++++++++++--------------
>  3 files changed, 44 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
> index 6122685..383e99f 100644
> --- a/drivers/bluetooth/btqca.c
> +++ b/drivers/bluetooth/btqca.c
> @@ -344,7 +344,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
>  
>  	/* Download rampatch file */
>  	config.type = TLV_TYPE_PATCH;
> -	if (soc_type == QCA_WCN3990) {
> +	if (qca_is_wcn399x(soc_type)) {
>  		/* Firmware files to download are based on ROM version.
>  		 * ROM version is derived from last two bytes of soc_ver.
>  		 */
> @@ -365,7 +365,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
>  
>  	/* Download NVM configuration */
>  	config.type = TLV_TYPE_NVM;
> -	if (soc_type == QCA_WCN3990)
> +	if (qca_is_wcn399x(soc_type))
>  		snprintf(config.fwname, sizeof(config.fwname),
>  			 "qca/crnv%02x.bin", rom_ver);
>  	else
> @@ -410,6 +410,15 @@ int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
>  }
>  EXPORT_SYMBOL_GPL(qca_set_bdaddr);
>  
> +bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
> +{
> +	if ((soc_type == QCA_WCN3990) || (soc_type == QCA_WCN3998))
> +		return true;
> +
> +	return false;
> +}
> +EXPORT_SYMBOL_GPL(qca_is_wcn399x);
> +
>  MODULE_AUTHOR("Ben Young Tae Kim <ytkim@qca.qualcomm.com>");
>  MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " VERSION);
>  MODULE_VERSION(VERSION);
> diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
> index 6fdc25d..0f68c9e7 100644
> --- a/drivers/bluetooth/btqca.h
> +++ b/drivers/bluetooth/btqca.h
> @@ -132,7 +132,8 @@ enum qca_btsoc_type {
>  	QCA_INVALID = -1,
>  	QCA_AR3002,
>  	QCA_ROME,
> -	QCA_WCN3990
> +	QCA_WCN3990,
> +	QCA_WCN3998,
>  };
>  
>  #if IS_ENABLED(CONFIG_BT_QCA)
> @@ -142,6 +143,7 @@ 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);
>  int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
> +bool qca_is_wcn399x(enum qca_btsoc_type soc_type);
>  #else
>  
>  static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
> @@ -165,4 +167,8 @@ static inline int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
>  	return -EOPNOTSUPP;
>  }
>  
> +static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
> +{
> +	return false;
> +}
>  #endif
> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> index 4ea995d..4af580a 100644
> --- a/drivers/bluetooth/hci_qca.c
> +++ b/drivers/bluetooth/hci_qca.c
> @@ -521,7 +521,7 @@ static int qca_open(struct hci_uart *hu)
>  	if (hu->serdev) {
>  
>  		qcadev = serdev_device_get_drvdata(hu->serdev);
> -		if (qcadev->btsoc_type != QCA_WCN3990) {
> +		if (!qca_is_wcn399x(qcadev->btsoc_type)) {
>  			gpiod_set_value_cansleep(qcadev->bt_en, 1);
>  		} else {
>  			hu->init_speed = qcadev->init_speed;
> @@ -627,7 +627,7 @@ static int qca_close(struct hci_uart *hu)
>  
>  	if (hu->serdev) {
>  		qcadev = serdev_device_get_drvdata(hu->serdev);
> -		if (qcadev->btsoc_type == QCA_WCN3990)
> +		if (qca_is_wcn399x(qcadev->btsoc_type))
>  			qca_power_shutdown(hu);
>  		else
>  			gpiod_set_value_cansleep(qcadev->bt_en, 0);
> @@ -1008,7 +1008,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
>  		      msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
>  
>  	/* Give the controller time to process the request */
> -	if (qca_soc_type(hu) == QCA_WCN3990)
> +	if (qca_is_wcn399x(qca_soc_type(hu)))
>  		msleep(10);
>  	else
>  		msleep(300);
> @@ -1084,7 +1084,7 @@ static unsigned int qca_get_speed(struct hci_uart *hu,
>  
>  static int qca_check_speeds(struct hci_uart *hu)
>  {
> -	if (qca_soc_type(hu) == QCA_WCN3990) {
> +	if (qca_is_wcn399x(qca_soc_type(hu))) {
>  		if (!qca_get_speed(hu, QCA_INIT_SPEED) &&
>  		    !qca_get_speed(hu, QCA_OPER_SPEED))
>  			return -EINVAL;
> @@ -1116,7 +1116,7 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
>  		/* Disable flow control for wcn3990 to deassert RTS while
>  		 * changing the baudrate of chip and host.
>  		 */
> -		if (soc_type == QCA_WCN3990)
> +		if (qca_is_wcn399x(soc_type))
>  			hci_uart_set_flow_control(hu, true);
>  
>  		qca_baudrate = qca_get_baudrate_value(speed);
> @@ -1128,7 +1128,7 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
>  		host_set_baudrate(hu, speed);
>  
>  error:
> -		if (soc_type == QCA_WCN3990)
> +		if (qca_is_wcn399x(soc_type))
>  			hci_uart_set_flow_control(hu, false);
>  	}
>  
> @@ -1201,7 +1201,7 @@ 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);
>  
> -	if (soc_type == QCA_WCN3990) {
> +	if (qca_is_wcn399x(soc_type)) {
>  		bt_dev_info(hdev, "setting up wcn3990");
>  
>  		/* Enable NON_PERSISTENT_SETUP QUIRK to ensure to execute
> @@ -1232,7 +1232,7 @@ static int qca_setup(struct hci_uart *hu)
>  		qca_baudrate = qca_get_baudrate_value(speed);
>  	}
>  
> -	if (soc_type != QCA_WCN3990) {
> +	if (!qca_is_wcn399x(soc_type)) {
>  		/* Get QCA version information */
>  		ret = qca_read_soc_version(hdev, &soc_ver);
>  		if (ret)
> @@ -1257,7 +1257,7 @@ static int qca_setup(struct hci_uart *hu)
>  	}
>  
>  	/* Setup bdaddr */
> -	if (soc_type == QCA_WCN3990)
> +	if (qca_is_wcn399x(soc_type))
>  		hu->hdev->set_bdaddr = qca_set_bdaddr;
>  	else
>  		hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
> @@ -1280,7 +1280,7 @@ static int qca_setup(struct hci_uart *hu)
>  	.dequeue	= qca_dequeue,
>  };
>  
> -static const struct qca_vreg_data qca_soc_data = {
> +static const struct qca_vreg_data qca_soc_data_wcn3990 = {
>  	.soc_type = QCA_WCN3990,
>  	.vregs = (struct qca_vreg []) {
>  		{ "vddio",   1800000, 1900000,  15000  },
> @@ -1291,6 +1291,17 @@ static int qca_setup(struct hci_uart *hu)
>  	.num_vregs = 4,
>  };
>  
> +static const struct qca_vreg_data qca_soc_data_wcn3998 = {
> +	.soc_type = QCA_WCN3998,
> +	.vregs = (struct qca_vreg []) {
> +		{ "vddio",   1800000, 1900000,  10000  },
> +		{ "vddxo",   1800000, 1900000,  80000  },
> +		{ "vddrf",   1300000, 1352000,  300000 },
> +		{ "vddch0",  3300000, 3300000,  450000 },
> +	},
> +	.num_vregs = 4,
> +};
> +
>  static void qca_power_shutdown(struct hci_uart *hu)
>  {
>  	struct qca_data *qca = hu->priv;
> @@ -1424,8 +1435,8 @@ static int qca_serdev_probe(struct serdev_device *serdev)
>  	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;
> +	if (data && qca_is_wcn399x(data->soc_type)) {
> +		qcadev->btsoc_type = data->soc_type;
>  		qcadev->bt_power = devm_kzalloc(&serdev->dev,
>  						sizeof(struct qca_power),
>  						GFP_KERNEL);
> @@ -1489,7 +1500,7 @@ static void qca_serdev_remove(struct serdev_device *serdev)
>  {
>  	struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
>  
> -	if (qcadev->btsoc_type == QCA_WCN3990)
> +	if (qca_is_wcn399x(qcadev->btsoc_type))
>  		qca_power_shutdown(&qcadev->serdev_hu);
>  	else
>  		clk_disable_unprepare(qcadev->susclk);
> @@ -1499,7 +1510,8 @@ static void qca_serdev_remove(struct serdev_device *serdev)
>  
>  static const struct of_device_id qca_bluetooth_of_match[] = {
>  	{ .compatible = "qcom,qca6174-bt" },
> -	{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data},
> +	{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990},
> +	{ .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998},
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);

Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

A suggestion for patch submission: it is often good to wait a few days
before sending a new revision to give other reviewers time to
comment. Reviewers may disagree with each other, this can then often
be sorted out on the mailing list, rather than changing the code back
and forth. Also it may save you a revision or two.

That said, there are no hard rules and there is nothing wrong with
being responsive, especially when bugs are pointed out. Just something
to keep in mind and consider on a per patch/revision basis :)

Cheers

Matthias
kernel test robot March 28, 2019, 9:05 p.m. UTC | #3
Hi Harish,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on bluetooth-next/master]
[also build test WARNING on next-20190328]
[cannot apply to v5.1-rc2]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Harish-Bandi/Bluetooth-hci_qca-Added-support-for-WCN3998/20190328-213357
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: riscv-allmodconfig (attached as .config)
compiler: riscv64-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=riscv 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers/bluetooth/btqca.c: In function 'qca_uart_setup':
>> drivers/bluetooth/btqca.c:369:3: warning: 'rom_ver' may be used uninitialized in this function [-Wmaybe-uninitialized]
      snprintf(config.fwname, sizeof(config.fwname),
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        "qca/crnv%02x.bin", rom_ver);
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/rom_ver +369 drivers/bluetooth/btqca.c

83e81961 Ben Young Tae Kim      2015-08-10  333  
aadebac4 Balakrishna Godavarthi 2018-08-03  334  int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
aadebac4 Balakrishna Godavarthi 2018-08-03  335  		   enum qca_btsoc_type soc_type, u32 soc_ver)
83e81961 Ben Young Tae Kim      2015-08-10  336  {
83e81961 Ben Young Tae Kim      2015-08-10  337  	struct rome_config config;
83e81961 Ben Young Tae Kim      2015-08-10  338  	int err;
4219d468 Balakrishna Godavarthi 2018-08-03  339  	u8 rom_ver;
83e81961 Ben Young Tae Kim      2015-08-10  340  
ba493d4f Balakrishna Godavarthi 2018-08-03  341  	bt_dev_dbg(hdev, "QCA setup on UART");
83e81961 Ben Young Tae Kim      2015-08-10  342  
83e81961 Ben Young Tae Kim      2015-08-10  343  	config.user_baud_rate = baudrate;
83e81961 Ben Young Tae Kim      2015-08-10  344  
83e81961 Ben Young Tae Kim      2015-08-10  345  	/* Download rampatch file */
83e81961 Ben Young Tae Kim      2015-08-10  346  	config.type = TLV_TYPE_PATCH;
cc8a70bd Harish Bandi           2019-03-27  347  	if (qca_is_wcn399x(soc_type)) {
4219d468 Balakrishna Godavarthi 2018-08-03  348  		/* Firmware files to download are based on ROM version.
4219d468 Balakrishna Godavarthi 2018-08-03  349  		 * ROM version is derived from last two bytes of soc_ver.
4219d468 Balakrishna Godavarthi 2018-08-03  350  		 */
4219d468 Balakrishna Godavarthi 2018-08-03  351  		rom_ver = ((soc_ver & 0x00000f00) >> 0x04) |
4219d468 Balakrishna Godavarthi 2018-08-03  352  			    (soc_ver & 0x0000000f);
4219d468 Balakrishna Godavarthi 2018-08-03  353  		snprintf(config.fwname, sizeof(config.fwname),
4219d468 Balakrishna Godavarthi 2018-08-03  354  			 "qca/crbtfw%02x.tlv", rom_ver);
4219d468 Balakrishna Godavarthi 2018-08-03  355  	} else {
4219d468 Balakrishna Godavarthi 2018-08-03  356  		snprintf(config.fwname, sizeof(config.fwname),
4219d468 Balakrishna Godavarthi 2018-08-03  357  			 "qca/rampatch_%08x.bin", soc_ver);
4219d468 Balakrishna Godavarthi 2018-08-03  358  	}
4219d468 Balakrishna Godavarthi 2018-08-03  359  
ba493d4f Balakrishna Godavarthi 2018-08-03  360  	err = qca_download_firmware(hdev, &config);
83e81961 Ben Young Tae Kim      2015-08-10  361  	if (err < 0) {
ba493d4f Balakrishna Godavarthi 2018-08-03  362  		bt_dev_err(hdev, "QCA Failed to download patch (%d)", err);
83e81961 Ben Young Tae Kim      2015-08-10  363  		return err;
83e81961 Ben Young Tae Kim      2015-08-10  364  	}
83e81961 Ben Young Tae Kim      2015-08-10  365  
83e81961 Ben Young Tae Kim      2015-08-10  366  	/* Download NVM configuration */
83e81961 Ben Young Tae Kim      2015-08-10  367  	config.type = TLV_TYPE_NVM;
cc8a70bd Harish Bandi           2019-03-27  368  	if (qca_is_wcn399x(soc_type))
4219d468 Balakrishna Godavarthi 2018-08-03 @369  		snprintf(config.fwname, sizeof(config.fwname),
4219d468 Balakrishna Godavarthi 2018-08-03  370  			 "qca/crnv%02x.bin", rom_ver);
4219d468 Balakrishna Godavarthi 2018-08-03  371  	else
4219d468 Balakrishna Godavarthi 2018-08-03  372  		snprintf(config.fwname, sizeof(config.fwname),
4219d468 Balakrishna Godavarthi 2018-08-03  373  			 "qca/nvm_%08x.bin", soc_ver);
4219d468 Balakrishna Godavarthi 2018-08-03  374  
ba493d4f Balakrishna Godavarthi 2018-08-03  375  	err = qca_download_firmware(hdev, &config);
83e81961 Ben Young Tae Kim      2015-08-10  376  	if (err < 0) {
ba493d4f Balakrishna Godavarthi 2018-08-03  377  		bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err);
83e81961 Ben Young Tae Kim      2015-08-10  378  		return err;
83e81961 Ben Young Tae Kim      2015-08-10  379  	}
83e81961 Ben Young Tae Kim      2015-08-10  380  
83e81961 Ben Young Tae Kim      2015-08-10  381  	/* Perform HCI reset */
ba493d4f Balakrishna Godavarthi 2018-08-03  382  	err = qca_send_reset(hdev);
83e81961 Ben Young Tae Kim      2015-08-10  383  	if (err < 0) {
ba493d4f Balakrishna Godavarthi 2018-08-03  384  		bt_dev_err(hdev, "QCA Failed to run HCI_RESET (%d)", err);
83e81961 Ben Young Tae Kim      2015-08-10  385  		return err;
83e81961 Ben Young Tae Kim      2015-08-10  386  	}
83e81961 Ben Young Tae Kim      2015-08-10  387  
ba493d4f Balakrishna Godavarthi 2018-08-03  388  	bt_dev_info(hdev, "QCA setup on UART is completed");
83e81961 Ben Young Tae Kim      2015-08-10  389  
83e81961 Ben Young Tae Kim      2015-08-10  390  	return 0;
83e81961 Ben Young Tae Kim      2015-08-10  391  }
ba493d4f Balakrishna Godavarthi 2018-08-03  392  EXPORT_SYMBOL_GPL(qca_uart_setup);
83e81961 Ben Young Tae Kim      2015-08-10  393  

:::::: The code at line 369 was first introduced by commit
:::::: 4219d4686875fdd83df3da00fda5ff0551e0a2d7 Bluetooth: btqca: Add wcn3990 firmware download support.

:::::: TO: Balakrishna Godavarthi <bgodavar@codeaurora.org>
:::::: CC: Marcel Holtmann <marcel@holtmann.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Matthias Kaehlcke March 28, 2019, 9:23 p.m. UTC | #4
On Fri, Mar 29, 2019 at 05:05:49AM +0800, kbuild test robot wrote:
> Hi Harish,
> 
> Thank you for the patch! Perhaps something to improve:
> 
> [auto build test WARNING on bluetooth-next/master]
> [also build test WARNING on next-20190328]
> [cannot apply to v5.1-rc2]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Harish-Bandi/Bluetooth-hci_qca-Added-support-for-WCN3998/20190328-213357
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
> config: riscv-allmodconfig (attached as .config)
> compiler: riscv64-linux-gcc (GCC) 8.1.0
> reproduce:
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # save the attached .config to linux build tree
>         GCC_VERSION=8.1.0 make.cross ARCH=riscv 
> 
> Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
> http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
> 
> All warnings (new ones prefixed by >>):
> 
>    drivers/bluetooth/btqca.c: In function 'qca_uart_setup':
> >> drivers/bluetooth/btqca.c:369:3: warning: 'rom_ver' may be used uninitialized in this function [-Wmaybe-uninitialized]
>       snprintf(config.fwname, sizeof(config.fwname),
>       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>         "qca/crnv%02x.bin", rom_ver);
>         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> vim +/rom_ver +369 drivers/bluetooth/btqca.c
> 
> 83e81961 Ben Young Tae Kim      2015-08-10  333  
> aadebac4 Balakrishna Godavarthi 2018-08-03  334  int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
> aadebac4 Balakrishna Godavarthi 2018-08-03  335  		   enum qca_btsoc_type soc_type, u32 soc_ver)
> 83e81961 Ben Young Tae Kim      2015-08-10  336  {
> 83e81961 Ben Young Tae Kim      2015-08-10  337  	struct rome_config config;
> 83e81961 Ben Young Tae Kim      2015-08-10  338  	int err;
> 4219d468 Balakrishna Godavarthi 2018-08-03  339  	u8 rom_ver;

With the use of qca_is_wcn399x() the compiler can't determine anymore
that rom_ver is only read for WCN399x, in which case it is also
initialized. Just initialize rom_ver with 0 to keep the compiler happy.

> 83e81961 Ben Young Tae Kim      2015-08-10  340  
> ba493d4f Balakrishna Godavarthi 2018-08-03  341  	bt_dev_dbg(hdev, "QCA setup on UART");
> 83e81961 Ben Young Tae Kim      2015-08-10  342  
> 83e81961 Ben Young Tae Kim      2015-08-10  343  	config.user_baud_rate = baudrate;
> 83e81961 Ben Young Tae Kim      2015-08-10  344  
> 83e81961 Ben Young Tae Kim      2015-08-10  345  	/* Download rampatch file */
> 83e81961 Ben Young Tae Kim      2015-08-10  346  	config.type = TLV_TYPE_PATCH;
> cc8a70bd Harish Bandi           2019-03-27  347  	if (qca_is_wcn399x(soc_type)) {
> 4219d468 Balakrishna Godavarthi 2018-08-03  348  		/* Firmware files to download are based on ROM version.
> 4219d468 Balakrishna Godavarthi 2018-08-03  349  		 * ROM version is derived from last two bytes of soc_ver.
> 4219d468 Balakrishna Godavarthi 2018-08-03  350  		 */
> 4219d468 Balakrishna Godavarthi 2018-08-03  351  		rom_ver = ((soc_ver & 0x00000f00) >> 0x04) |
> 4219d468 Balakrishna Godavarthi 2018-08-03  352  			    (soc_ver & 0x0000000f);
> 4219d468 Balakrishna Godavarthi 2018-08-03  353  		snprintf(config.fwname, sizeof(config.fwname),
> 4219d468 Balakrishna Godavarthi 2018-08-03  354  			 "qca/crbtfw%02x.tlv", rom_ver);
> 4219d468 Balakrishna Godavarthi 2018-08-03  355  	} else {
> 4219d468 Balakrishna Godavarthi 2018-08-03  356  		snprintf(config.fwname, sizeof(config.fwname),
> 4219d468 Balakrishna Godavarthi 2018-08-03  357  			 "qca/rampatch_%08x.bin", soc_ver);
> 4219d468 Balakrishna Godavarthi 2018-08-03  358  	}
> 4219d468 Balakrishna Godavarthi 2018-08-03  359  
> ba493d4f Balakrishna Godavarthi 2018-08-03  360  	err = qca_download_firmware(hdev, &config);
> 83e81961 Ben Young Tae Kim      2015-08-10  361  	if (err < 0) {
> ba493d4f Balakrishna Godavarthi 2018-08-03  362  		bt_dev_err(hdev, "QCA Failed to download patch (%d)", err);
> 83e81961 Ben Young Tae Kim      2015-08-10  363  		return err;
> 83e81961 Ben Young Tae Kim      2015-08-10  364  	}
> 83e81961 Ben Young Tae Kim      2015-08-10  365  
> 83e81961 Ben Young Tae Kim      2015-08-10  366  	/* Download NVM configuration */
> 83e81961 Ben Young Tae Kim      2015-08-10  367  	config.type = TLV_TYPE_NVM;
> cc8a70bd Harish Bandi           2019-03-27  368  	if (qca_is_wcn399x(soc_type))
> 4219d468 Balakrishna Godavarthi 2018-08-03 @369  		snprintf(config.fwname, sizeof(config.fwname),
> 4219d468 Balakrishna Godavarthi 2018-08-03  370  			 "qca/crnv%02x.bin", rom_ver);
> 4219d468 Balakrishna Godavarthi 2018-08-03  371  	else
> 4219d468 Balakrishna Godavarthi 2018-08-03  372  		snprintf(config.fwname, sizeof(config.fwname),
> 4219d468 Balakrishna Godavarthi 2018-08-03  373  			 "qca/nvm_%08x.bin", soc_ver);
> 4219d468 Balakrishna Godavarthi 2018-08-03  374  
> ba493d4f Balakrishna Godavarthi 2018-08-03  375  	err = qca_download_firmware(hdev, &config);
> 83e81961 Ben Young Tae Kim      2015-08-10  376  	if (err < 0) {
> ba493d4f Balakrishna Godavarthi 2018-08-03  377  		bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err);
> 83e81961 Ben Young Tae Kim      2015-08-10  378  		return err;
> 83e81961 Ben Young Tae Kim      2015-08-10  379  	}
> 83e81961 Ben Young Tae Kim      2015-08-10  380  
> 83e81961 Ben Young Tae Kim      2015-08-10  381  	/* Perform HCI reset */
> ba493d4f Balakrishna Godavarthi 2018-08-03  382  	err = qca_send_reset(hdev);
> 83e81961 Ben Young Tae Kim      2015-08-10  383  	if (err < 0) {
> ba493d4f Balakrishna Godavarthi 2018-08-03  384  		bt_dev_err(hdev, "QCA Failed to run HCI_RESET (%d)", err);
> 83e81961 Ben Young Tae Kim      2015-08-10  385  		return err;
> 83e81961 Ben Young Tae Kim      2015-08-10  386  	}
> 83e81961 Ben Young Tae Kim      2015-08-10  387  
> ba493d4f Balakrishna Godavarthi 2018-08-03  388  	bt_dev_info(hdev, "QCA setup on UART is completed");
> 83e81961 Ben Young Tae Kim      2015-08-10  389  
> 83e81961 Ben Young Tae Kim      2015-08-10  390  	return 0;
> 83e81961 Ben Young Tae Kim      2015-08-10  391  }
> ba493d4f Balakrishna Godavarthi 2018-08-03  392  EXPORT_SYMBOL_GPL(qca_uart_setup);
> 83e81961 Ben Young Tae Kim      2015-08-10  393  
> 
> :::::: The code at line 369 was first introduced by commit
> :::::: 4219d4686875fdd83df3da00fda5ff0551e0a2d7 Bluetooth: btqca: Add wcn3990 firmware download support.
> 
> :::::: TO: Balakrishna Godavarthi <bgodavar@codeaurora.org>
> :::::: CC: Marcel Holtmann <marcel@holtmann.org>
> 
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Harish Bandi March 29, 2019, 4:40 a.m. UTC | #5
Hi Matthias,

On 2019-03-27 22:26, Matthias Kaehlcke wrote:
> On Wed, Mar 27, 2019 at 05:58:42PM +0530, Harish Bandi wrote:
>> Added new compatible for WCN3998 and corresponding voltage
>> and current values to WCN3998 compatible.
>> Changed driver code to support WCN3998
>> 
>> Signed-off-by: Harish Bandi <c-hbandi@codeaurora.org>
> 
> You forgot to add 'Reviewed-by' my tag from v5. No need to resend,
> I'll add it again below, but it's the general practice to include tags
> like 'Reviewed-by' or 'Acked-by' when sending a new revision.
> 
[Harish] - sorry for missing, will follow from new version.
>> ---
>> Changes in V6:
>> - changed return value to false in the qca_is_wcn399x()stub
>> ---
>>  drivers/bluetooth/btqca.c   | 13 +++++++++++--
>>  drivers/bluetooth/btqca.h   |  8 +++++++-
>>  drivers/bluetooth/hci_qca.c | 40 
>> ++++++++++++++++++++++++++--------------
>>  3 files changed, 44 insertions(+), 17 deletions(-)
>> 
>> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
>> index 6122685..383e99f 100644
>> --- a/drivers/bluetooth/btqca.c
>> +++ b/drivers/bluetooth/btqca.c
>> @@ -344,7 +344,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t 
>> baudrate,
>> 
>>  	/* Download rampatch file */
>>  	config.type = TLV_TYPE_PATCH;
>> -	if (soc_type == QCA_WCN3990) {
>> +	if (qca_is_wcn399x(soc_type)) {
>>  		/* Firmware files to download are based on ROM version.
>>  		 * ROM version is derived from last two bytes of soc_ver.
>>  		 */
>> @@ -365,7 +365,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t 
>> baudrate,
>> 
>>  	/* Download NVM configuration */
>>  	config.type = TLV_TYPE_NVM;
>> -	if (soc_type == QCA_WCN3990)
>> +	if (qca_is_wcn399x(soc_type))
>>  		snprintf(config.fwname, sizeof(config.fwname),
>>  			 "qca/crnv%02x.bin", rom_ver);
>>  	else
>> @@ -410,6 +410,15 @@ int qca_set_bdaddr(struct hci_dev *hdev, const 
>> bdaddr_t *bdaddr)
>>  }
>>  EXPORT_SYMBOL_GPL(qca_set_bdaddr);
>> 
>> +bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
>> +{
>> +	if ((soc_type == QCA_WCN3990) || (soc_type == QCA_WCN3998))
>> +		return true;
>> +
>> +	return false;
>> +}
>> +EXPORT_SYMBOL_GPL(qca_is_wcn399x);
>> +
>>  MODULE_AUTHOR("Ben Young Tae Kim <ytkim@qca.qualcomm.com>");
>>  MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver 
>> " VERSION);
>>  MODULE_VERSION(VERSION);
>> diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
>> index 6fdc25d..0f68c9e7 100644
>> --- a/drivers/bluetooth/btqca.h
>> +++ b/drivers/bluetooth/btqca.h
>> @@ -132,7 +132,8 @@ enum qca_btsoc_type {
>>  	QCA_INVALID = -1,
>>  	QCA_AR3002,
>>  	QCA_ROME,
>> -	QCA_WCN3990
>> +	QCA_WCN3990,
>> +	QCA_WCN3998,
>>  };
>> 
>>  #if IS_ENABLED(CONFIG_BT_QCA)
>> @@ -142,6 +143,7 @@ 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);
>>  int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
>> +bool qca_is_wcn399x(enum qca_btsoc_type soc_type);
>>  #else
>> 
>>  static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const 
>> bdaddr_t *bdaddr)
>> @@ -165,4 +167,8 @@ static inline int qca_set_bdaddr(struct hci_dev 
>> *hdev, const bdaddr_t *bdaddr)
>>  	return -EOPNOTSUPP;
>>  }
>> 
>> +static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
>> +{
>> +	return false;
>> +}
>>  #endif
>> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
>> index 4ea995d..4af580a 100644
>> --- a/drivers/bluetooth/hci_qca.c
>> +++ b/drivers/bluetooth/hci_qca.c
>> @@ -521,7 +521,7 @@ static int qca_open(struct hci_uart *hu)
>>  	if (hu->serdev) {
>> 
>>  		qcadev = serdev_device_get_drvdata(hu->serdev);
>> -		if (qcadev->btsoc_type != QCA_WCN3990) {
>> +		if (!qca_is_wcn399x(qcadev->btsoc_type)) {
>>  			gpiod_set_value_cansleep(qcadev->bt_en, 1);
>>  		} else {
>>  			hu->init_speed = qcadev->init_speed;
>> @@ -627,7 +627,7 @@ static int qca_close(struct hci_uart *hu)
>> 
>>  	if (hu->serdev) {
>>  		qcadev = serdev_device_get_drvdata(hu->serdev);
>> -		if (qcadev->btsoc_type == QCA_WCN3990)
>> +		if (qca_is_wcn399x(qcadev->btsoc_type))
>>  			qca_power_shutdown(hu);
>>  		else
>>  			gpiod_set_value_cansleep(qcadev->bt_en, 0);
>> @@ -1008,7 +1008,7 @@ static int qca_set_baudrate(struct hci_dev 
>> *hdev, uint8_t baudrate)
>>  		      msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
>> 
>>  	/* Give the controller time to process the request */
>> -	if (qca_soc_type(hu) == QCA_WCN3990)
>> +	if (qca_is_wcn399x(qca_soc_type(hu)))
>>  		msleep(10);
>>  	else
>>  		msleep(300);
>> @@ -1084,7 +1084,7 @@ static unsigned int qca_get_speed(struct 
>> hci_uart *hu,
>> 
>>  static int qca_check_speeds(struct hci_uart *hu)
>>  {
>> -	if (qca_soc_type(hu) == QCA_WCN3990) {
>> +	if (qca_is_wcn399x(qca_soc_type(hu))) {
>>  		if (!qca_get_speed(hu, QCA_INIT_SPEED) &&
>>  		    !qca_get_speed(hu, QCA_OPER_SPEED))
>>  			return -EINVAL;
>> @@ -1116,7 +1116,7 @@ static int qca_set_speed(struct hci_uart *hu, 
>> enum qca_speed_type speed_type)
>>  		/* Disable flow control for wcn3990 to deassert RTS while
>>  		 * changing the baudrate of chip and host.
>>  		 */
>> -		if (soc_type == QCA_WCN3990)
>> +		if (qca_is_wcn399x(soc_type))
>>  			hci_uart_set_flow_control(hu, true);
>> 
>>  		qca_baudrate = qca_get_baudrate_value(speed);
>> @@ -1128,7 +1128,7 @@ static int qca_set_speed(struct hci_uart *hu, 
>> enum qca_speed_type speed_type)
>>  		host_set_baudrate(hu, speed);
>> 
>>  error:
>> -		if (soc_type == QCA_WCN3990)
>> +		if (qca_is_wcn399x(soc_type))
>>  			hci_uart_set_flow_control(hu, false);
>>  	}
>> 
>> @@ -1201,7 +1201,7 @@ 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);
>> 
>> -	if (soc_type == QCA_WCN3990) {
>> +	if (qca_is_wcn399x(soc_type)) {
>>  		bt_dev_info(hdev, "setting up wcn3990");
>> 
>>  		/* Enable NON_PERSISTENT_SETUP QUIRK to ensure to execute
>> @@ -1232,7 +1232,7 @@ static int qca_setup(struct hci_uart *hu)
>>  		qca_baudrate = qca_get_baudrate_value(speed);
>>  	}
>> 
>> -	if (soc_type != QCA_WCN3990) {
>> +	if (!qca_is_wcn399x(soc_type)) {
>>  		/* Get QCA version information */
>>  		ret = qca_read_soc_version(hdev, &soc_ver);
>>  		if (ret)
>> @@ -1257,7 +1257,7 @@ static int qca_setup(struct hci_uart *hu)
>>  	}
>> 
>>  	/* Setup bdaddr */
>> -	if (soc_type == QCA_WCN3990)
>> +	if (qca_is_wcn399x(soc_type))
>>  		hu->hdev->set_bdaddr = qca_set_bdaddr;
>>  	else
>>  		hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
>> @@ -1280,7 +1280,7 @@ static int qca_setup(struct hci_uart *hu)
>>  	.dequeue	= qca_dequeue,
>>  };
>> 
>> -static const struct qca_vreg_data qca_soc_data = {
>> +static const struct qca_vreg_data qca_soc_data_wcn3990 = {
>>  	.soc_type = QCA_WCN3990,
>>  	.vregs = (struct qca_vreg []) {
>>  		{ "vddio",   1800000, 1900000,  15000  },
>> @@ -1291,6 +1291,17 @@ static int qca_setup(struct hci_uart *hu)
>>  	.num_vregs = 4,
>>  };
>> 
>> +static const struct qca_vreg_data qca_soc_data_wcn3998 = {
>> +	.soc_type = QCA_WCN3998,
>> +	.vregs = (struct qca_vreg []) {
>> +		{ "vddio",   1800000, 1900000,  10000  },
>> +		{ "vddxo",   1800000, 1900000,  80000  },
>> +		{ "vddrf",   1300000, 1352000,  300000 },
>> +		{ "vddch0",  3300000, 3300000,  450000 },
>> +	},
>> +	.num_vregs = 4,
>> +};
>> +
>>  static void qca_power_shutdown(struct hci_uart *hu)
>>  {
>>  	struct qca_data *qca = hu->priv;
>> @@ -1424,8 +1435,8 @@ static int qca_serdev_probe(struct serdev_device 
>> *serdev)
>>  	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;
>> +	if (data && qca_is_wcn399x(data->soc_type)) {
>> +		qcadev->btsoc_type = data->soc_type;
>>  		qcadev->bt_power = devm_kzalloc(&serdev->dev,
>>  						sizeof(struct qca_power),
>>  						GFP_KERNEL);
>> @@ -1489,7 +1500,7 @@ static void qca_serdev_remove(struct 
>> serdev_device *serdev)
>>  {
>>  	struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
>> 
>> -	if (qcadev->btsoc_type == QCA_WCN3990)
>> +	if (qca_is_wcn399x(qcadev->btsoc_type))
>>  		qca_power_shutdown(&qcadev->serdev_hu);
>>  	else
>>  		clk_disable_unprepare(qcadev->susclk);
>> @@ -1499,7 +1510,8 @@ static void qca_serdev_remove(struct 
>> serdev_device *serdev)
>> 
>>  static const struct of_device_id qca_bluetooth_of_match[] = {
>>  	{ .compatible = "qcom,qca6174-bt" },
>> -	{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data},
>> +	{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990},
>> +	{ .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998},
>>  	{ /* sentinel */ }
>>  };
>>  MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);
> 
> Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
> 
> A suggestion for patch submission: it is often good to wait a few days
> before sending a new revision to give other reviewers time to
> comment. Reviewers may disagree with each other, this can then often
> be sorted out on the mailing list, rather than changing the code back
> and forth. Also it may save you a revision or two.
> 
> That said, there are no hard rules and there is nothing wrong with
> being responsive, especially when bugs are pointed out. Just something
> to keep in mind and consider on a per patch/revision basis :)
> 
[Harish] - Sure.

> Cheers
> 
> Matthias
Harish Bandi March 29, 2019, 4:42 a.m. UTC | #6
Hi Matthias,

On 2019-03-29 02:53, Matthias Kaehlcke wrote:
> On Fri, Mar 29, 2019 at 05:05:49AM +0800, kbuild test robot wrote:
>> Hi Harish,
>> 
>> Thank you for the patch! Perhaps something to improve:
>> 
>> [auto build test WARNING on bluetooth-next/master]
>> [also build test WARNING on next-20190328]
>> [cannot apply to v5.1-rc2]
>> [if your patch is applied to the wrong git tree, please drop us a note 
>> to help improve the system]
>> 
>> url:    
>> https://github.com/0day-ci/linux/commits/Harish-Bandi/Bluetooth-hci_qca-Added-support-for-WCN3998/20190328-213357
>> base:   
>> https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git 
>> master
>> config: riscv-allmodconfig (attached as .config)
>> compiler: riscv64-linux-gcc (GCC) 8.1.0
>> reproduce:
>>         wget 
>> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross 
>> -O ~/bin/make.cross
>>         chmod +x ~/bin/make.cross
>>         # save the attached .config to linux build tree
>>         GCC_VERSION=8.1.0 make.cross ARCH=riscv
>> 
>> Note: it may well be a FALSE warning. FWIW you are at least aware of 
>> it now.
>> http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
>> 
>> All warnings (new ones prefixed by >>):
>> 
>>    drivers/bluetooth/btqca.c: In function 'qca_uart_setup':
>> >> drivers/bluetooth/btqca.c:369:3: warning: 'rom_ver' may be used uninitialized in this function [-Wmaybe-uninitialized]
>>       snprintf(config.fwname, sizeof(config.fwname),
>>       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>         "qca/crnv%02x.bin", rom_ver);
>>         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> 
>> vim +/rom_ver +369 drivers/bluetooth/btqca.c
>> 
>> 83e81961 Ben Young Tae Kim      2015-08-10  333
>> aadebac4 Balakrishna Godavarthi 2018-08-03  334  int 
>> qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
>> aadebac4 Balakrishna Godavarthi 2018-08-03  335  		   enum 
>> qca_btsoc_type soc_type, u32 soc_ver)
>> 83e81961 Ben Young Tae Kim      2015-08-10  336  {
>> 83e81961 Ben Young Tae Kim      2015-08-10  337  	struct rome_config 
>> config;
>> 83e81961 Ben Young Tae Kim      2015-08-10  338  	int err;
>> 4219d468 Balakrishna Godavarthi 2018-08-03  339  	u8 rom_ver;
> 
> With the use of qca_is_wcn399x() the compiler can't determine anymore
> that rom_ver is only read for WCN399x, in which case it is also
> initialized. Just initialize rom_ver with 0 to keep the compiler happy.
> 
[Harish] - sure, will wait for few more comments and address all 
comments in new patch version.

>> 83e81961 Ben Young Tae Kim      2015-08-10  340
>> ba493d4f Balakrishna Godavarthi 2018-08-03  341  	bt_dev_dbg(hdev, 
>> "QCA setup on UART");
>> 83e81961 Ben Young Tae Kim      2015-08-10  342
>> 83e81961 Ben Young Tae Kim      2015-08-10  343  
>> 	config.user_baud_rate = baudrate;
>> 83e81961 Ben Young Tae Kim      2015-08-10  344
>> 83e81961 Ben Young Tae Kim      2015-08-10  345  	/* Download rampatch 
>> file */
>> 83e81961 Ben Young Tae Kim      2015-08-10  346  	config.type = 
>> TLV_TYPE_PATCH;
>> cc8a70bd Harish Bandi           2019-03-27  347  	if 
>> (qca_is_wcn399x(soc_type)) {
>> 4219d468 Balakrishna Godavarthi 2018-08-03  348  		/* Firmware files 
>> to download are based on ROM version.
>> 4219d468 Balakrishna Godavarthi 2018-08-03  349  		 * ROM version is 
>> derived from last two bytes of soc_ver.
>> 4219d468 Balakrishna Godavarthi 2018-08-03  350  		 */
>> 4219d468 Balakrishna Godavarthi 2018-08-03  351  		rom_ver = ((soc_ver 
>> & 0x00000f00) >> 0x04) |
>> 4219d468 Balakrishna Godavarthi 2018-08-03  352  			    (soc_ver & 
>> 0x0000000f);
>> 4219d468 Balakrishna Godavarthi 2018-08-03  353  
>> 		snprintf(config.fwname, sizeof(config.fwname),
>> 4219d468 Balakrishna Godavarthi 2018-08-03  354  			 
>> "qca/crbtfw%02x.tlv", rom_ver);
>> 4219d468 Balakrishna Godavarthi 2018-08-03  355  	} else {
>> 4219d468 Balakrishna Godavarthi 2018-08-03  356  
>> 		snprintf(config.fwname, sizeof(config.fwname),
>> 4219d468 Balakrishna Godavarthi 2018-08-03  357  			 
>> "qca/rampatch_%08x.bin", soc_ver);
>> 4219d468 Balakrishna Godavarthi 2018-08-03  358  	}
>> 4219d468 Balakrishna Godavarthi 2018-08-03  359
>> ba493d4f Balakrishna Godavarthi 2018-08-03  360  	err = 
>> qca_download_firmware(hdev, &config);
>> 83e81961 Ben Young Tae Kim      2015-08-10  361  	if (err < 0) {
>> ba493d4f Balakrishna Godavarthi 2018-08-03  362  		bt_dev_err(hdev, 
>> "QCA Failed to download patch (%d)", err);
>> 83e81961 Ben Young Tae Kim      2015-08-10  363  		return err;
>> 83e81961 Ben Young Tae Kim      2015-08-10  364  	}
>> 83e81961 Ben Young Tae Kim      2015-08-10  365
>> 83e81961 Ben Young Tae Kim      2015-08-10  366  	/* Download NVM 
>> configuration */
>> 83e81961 Ben Young Tae Kim      2015-08-10  367  	config.type = 
>> TLV_TYPE_NVM;
>> cc8a70bd Harish Bandi           2019-03-27  368  	if 
>> (qca_is_wcn399x(soc_type))
>> 4219d468 Balakrishna Godavarthi 2018-08-03 @369  
>> 		snprintf(config.fwname, sizeof(config.fwname),
>> 4219d468 Balakrishna Godavarthi 2018-08-03  370  			 
>> "qca/crnv%02x.bin", rom_ver);
>> 4219d468 Balakrishna Godavarthi 2018-08-03  371  	else
>> 4219d468 Balakrishna Godavarthi 2018-08-03  372  
>> 		snprintf(config.fwname, sizeof(config.fwname),
>> 4219d468 Balakrishna Godavarthi 2018-08-03  373  			 
>> "qca/nvm_%08x.bin", soc_ver);
>> 4219d468 Balakrishna Godavarthi 2018-08-03  374
>> ba493d4f Balakrishna Godavarthi 2018-08-03  375  	err = 
>> qca_download_firmware(hdev, &config);
>> 83e81961 Ben Young Tae Kim      2015-08-10  376  	if (err < 0) {
>> ba493d4f Balakrishna Godavarthi 2018-08-03  377  		bt_dev_err(hdev, 
>> "QCA Failed to download NVM (%d)", err);
>> 83e81961 Ben Young Tae Kim      2015-08-10  378  		return err;
>> 83e81961 Ben Young Tae Kim      2015-08-10  379  	}
>> 83e81961 Ben Young Tae Kim      2015-08-10  380
>> 83e81961 Ben Young Tae Kim      2015-08-10  381  	/* Perform HCI reset 
>> */
>> ba493d4f Balakrishna Godavarthi 2018-08-03  382  	err = 
>> qca_send_reset(hdev);
>> 83e81961 Ben Young Tae Kim      2015-08-10  383  	if (err < 0) {
>> ba493d4f Balakrishna Godavarthi 2018-08-03  384  		bt_dev_err(hdev, 
>> "QCA Failed to run HCI_RESET (%d)", err);
>> 83e81961 Ben Young Tae Kim      2015-08-10  385  		return err;
>> 83e81961 Ben Young Tae Kim      2015-08-10  386  	}
>> 83e81961 Ben Young Tae Kim      2015-08-10  387
>> ba493d4f Balakrishna Godavarthi 2018-08-03  388  	bt_dev_info(hdev, 
>> "QCA setup on UART is completed");
>> 83e81961 Ben Young Tae Kim      2015-08-10  389
>> 83e81961 Ben Young Tae Kim      2015-08-10  390  	return 0;
>> 83e81961 Ben Young Tae Kim      2015-08-10  391  }
>> ba493d4f Balakrishna Godavarthi 2018-08-03  392  
>> EXPORT_SYMBOL_GPL(qca_uart_setup);
>> 83e81961 Ben Young Tae Kim      2015-08-10  393
>> 
>> :::::: The code at line 369 was first introduced by commit
>> :::::: 4219d4686875fdd83df3da00fda5ff0551e0a2d7 Bluetooth: btqca: Add 
>> wcn3990 firmware download support.
>> 
>> :::::: TO: Balakrishna Godavarthi <bgodavar@codeaurora.org>
>> :::::: CC: Marcel Holtmann <marcel@holtmann.org>
>> 
>> ---
>> 0-DAY kernel test infrastructure                Open Source Technology 
>> Center
>> https://lists.01.org/pipermail/kbuild-all                   Intel 
>> Corporation

Thanks,
Harish
Marc Gonzalez April 1, 2019, 4:16 p.m. UTC | #7
On 27/03/2019 13:28, Harish Bandi wrote:

> +bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
> +{
> +	if ((soc_type == QCA_WCN3990) || (soc_type == QCA_WCN3998))
> +		return true;
> +
> +	return false;
> +}

Dunno if you saw my earlier comment.

The above is not very idiomatic. I would write:

bool is_qca_soc_type_wcn399x_family(enum qca_btsoc_type soc_type)
{
	return soc_type == QCA_WCN3990 || soc_type  == QCA_WCN3998;
}

Regards.
Harish Bandi July 5, 2019, 7:33 a.m. UTC | #8
Hi Marcel/Bluetooth Maintainers,

In hci_dev_do_close first it is sending vendor specific shutdown routine 
and then after some operations it is sending
the hci_reset command.
However in vendor specific shutdown routine if vendor already powered 
off the vendor chip. In those cases it will not
send the HCI_RESET command. That may lead to bug or some cleanup 
operations not done properly in Chip.
Is there any specific reason why it is sending vendor specific shutdown 
routine first and then sending HCI_RESET command.


int hci_dev_do_close(struct hci_dev *hdev)
{
	bool auto_off;

	BT_DBG("%s %p", hdev->name, hdev);

	if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
	    test_bit(HCI_UP, &hdev->flags)) {
		/* Execute vendor specific shutdown routine */
		if (hdev->shutdown)
			hdev->shutdown(hdev);
	}

	cancel_delayed_work(&hdev->power_off);

	hci_request_cancel_all(hdev);
	hci_req_sync_lock(hdev);

	if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
		cancel_delayed_work_sync(&hdev->cmd_timer);
		hci_req_sync_unlock(hdev);
		return 0;
	}

	hci_leds_update_powered(hdev, false);

	/* Flush RX and TX works */
	flush_work(&hdev->tx_work);
	flush_work(&hdev->rx_work);

	if (hdev->discov_timeout > 0) {
		hdev->discov_timeout = 0;
		hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
		hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
	}

	if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
		cancel_delayed_work(&hdev->service_cache);

	if (hci_dev_test_flag(hdev, HCI_MGMT)) {
		struct adv_info *adv_instance;

		cancel_delayed_work_sync(&hdev->rpa_expired);

		list_for_each_entry(adv_instance, &hdev->adv_instances, list)
			cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
	}

	/* Avoid potential lockdep warnings from the *_flush() calls by
	 * ensuring the workqueue is empty up front.
	 */
	drain_workqueue(hdev->workqueue);

	hci_dev_lock(hdev);

	hci_discovery_set_state(hdev, DISCOVERY_STOPPED);

	auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF);

	if (!auto_off && hdev->dev_type == HCI_PRIMARY &&
	    !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
	    hci_dev_test_flag(hdev, HCI_MGMT))
		__mgmt_power_off(hdev);

	hci_inquiry_cache_flush(hdev);
	hci_pend_le_actions_clear(hdev);
	hci_conn_hash_flush(hdev);
	hci_dev_unlock(hdev);

	smp_unregister(hdev);

	hci_sock_dev_event(hdev, HCI_DEV_DOWN);

	if (hdev->flush)
		hdev->flush(hdev);

	/* Reset device */
	skb_queue_purge(&hdev->cmd_q);
	atomic_set(&hdev->cmd_cnt, 1);
	if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) &&
	    !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
		set_bit(HCI_INIT, &hdev->flags);
		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL);
		clear_bit(HCI_INIT, &hdev->flags);
	}

	/* flush cmd  work */
	flush_work(&hdev->cmd_work);

	/* Drop queues */
	skb_queue_purge(&hdev->rx_q);
	skb_queue_purge(&hdev->cmd_q);
	skb_queue_purge(&hdev->raw_q);

	/* Drop last sent command */
	if (hdev->sent_cmd) {
		cancel_delayed_work_sync(&hdev->cmd_timer);
		kfree_skb(hdev->sent_cmd);
		hdev->sent_cmd = NULL;
	}

	clear_bit(HCI_RUNNING, &hdev->flags);
	hci_sock_dev_event(hdev, HCI_DEV_CLOSE);

	/* After this point our queues are empty
	 * and no tasks are scheduled. */
	hdev->close(hdev);

	/* Clear flags */
	hdev->flags &= BIT(HCI_RAW);
	hci_dev_clear_volatile_flags(hdev);

	/* Controller radio is available but is currently powered down */
	hdev->amp_status = AMP_STATUS_POWERED_DOWN;

	memset(hdev->eir, 0, sizeof(hdev->eir));
	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
	bacpy(&hdev->random_addr, BDADDR_ANY);

	hci_req_sync_unlock(hdev);

	hci_dev_put(hdev);
	return 0;
}
Marcel Holtmann July 6, 2019, 10:22 a.m. UTC | #9
Hi Harish,

> In hci_dev_do_close first it is sending vendor specific shutdown routine and then after some operations it is sending
> the hci_reset command.
> However in vendor specific shutdown routine if vendor already powered off the vendor chip. In those cases it will not
> send the HCI_RESET command. That may lead to bug or some cleanup operations not done properly in Chip.
> Is there any specific reason why it is sending vendor specific shutdown routine first and then sending HCI_RESET command.

are you setting HCI_QUIRK_RESET_ON_CLOSE and trying to use hdev->shutdown at the same time. That is not how this is suppose to be used. The HCI_QUIRK_RESET_ON_CLOSE is just for old Bluetooth 1.0b USB devices.

Regards

Marcel
diff mbox series

Patch

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index 6122685..383e99f 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -344,7 +344,7 @@  int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 
 	/* Download rampatch file */
 	config.type = TLV_TYPE_PATCH;
-	if (soc_type == QCA_WCN3990) {
+	if (qca_is_wcn399x(soc_type)) {
 		/* Firmware files to download are based on ROM version.
 		 * ROM version is derived from last two bytes of soc_ver.
 		 */
@@ -365,7 +365,7 @@  int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 
 	/* Download NVM configuration */
 	config.type = TLV_TYPE_NVM;
-	if (soc_type == QCA_WCN3990)
+	if (qca_is_wcn399x(soc_type))
 		snprintf(config.fwname, sizeof(config.fwname),
 			 "qca/crnv%02x.bin", rom_ver);
 	else
@@ -410,6 +410,15 @@  int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 }
 EXPORT_SYMBOL_GPL(qca_set_bdaddr);
 
+bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
+{
+	if ((soc_type == QCA_WCN3990) || (soc_type == QCA_WCN3998))
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL_GPL(qca_is_wcn399x);
+
 MODULE_AUTHOR("Ben Young Tae Kim <ytkim@qca.qualcomm.com>");
 MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " VERSION);
 MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/btqca.h b/drivers/bluetooth/btqca.h
index 6fdc25d..0f68c9e7 100644
--- a/drivers/bluetooth/btqca.h
+++ b/drivers/bluetooth/btqca.h
@@ -132,7 +132,8 @@  enum qca_btsoc_type {
 	QCA_INVALID = -1,
 	QCA_AR3002,
 	QCA_ROME,
-	QCA_WCN3990
+	QCA_WCN3990,
+	QCA_WCN3998,
 };
 
 #if IS_ENABLED(CONFIG_BT_QCA)
@@ -142,6 +143,7 @@  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);
 int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
+bool qca_is_wcn399x(enum qca_btsoc_type soc_type);
 #else
 
 static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
@@ -165,4 +167,8 @@  static inline int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 	return -EOPNOTSUPP;
 }
 
+static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
+{
+	return false;
+}
 #endif
diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
index 4ea995d..4af580a 100644
--- a/drivers/bluetooth/hci_qca.c
+++ b/drivers/bluetooth/hci_qca.c
@@ -521,7 +521,7 @@  static int qca_open(struct hci_uart *hu)
 	if (hu->serdev) {
 
 		qcadev = serdev_device_get_drvdata(hu->serdev);
-		if (qcadev->btsoc_type != QCA_WCN3990) {
+		if (!qca_is_wcn399x(qcadev->btsoc_type)) {
 			gpiod_set_value_cansleep(qcadev->bt_en, 1);
 		} else {
 			hu->init_speed = qcadev->init_speed;
@@ -627,7 +627,7 @@  static int qca_close(struct hci_uart *hu)
 
 	if (hu->serdev) {
 		qcadev = serdev_device_get_drvdata(hu->serdev);
-		if (qcadev->btsoc_type == QCA_WCN3990)
+		if (qca_is_wcn399x(qcadev->btsoc_type))
 			qca_power_shutdown(hu);
 		else
 			gpiod_set_value_cansleep(qcadev->bt_en, 0);
@@ -1008,7 +1008,7 @@  static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
 		      msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
 
 	/* Give the controller time to process the request */
-	if (qca_soc_type(hu) == QCA_WCN3990)
+	if (qca_is_wcn399x(qca_soc_type(hu)))
 		msleep(10);
 	else
 		msleep(300);
@@ -1084,7 +1084,7 @@  static unsigned int qca_get_speed(struct hci_uart *hu,
 
 static int qca_check_speeds(struct hci_uart *hu)
 {
-	if (qca_soc_type(hu) == QCA_WCN3990) {
+	if (qca_is_wcn399x(qca_soc_type(hu))) {
 		if (!qca_get_speed(hu, QCA_INIT_SPEED) &&
 		    !qca_get_speed(hu, QCA_OPER_SPEED))
 			return -EINVAL;
@@ -1116,7 +1116,7 @@  static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
 		/* Disable flow control for wcn3990 to deassert RTS while
 		 * changing the baudrate of chip and host.
 		 */
-		if (soc_type == QCA_WCN3990)
+		if (qca_is_wcn399x(soc_type))
 			hci_uart_set_flow_control(hu, true);
 
 		qca_baudrate = qca_get_baudrate_value(speed);
@@ -1128,7 +1128,7 @@  static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
 		host_set_baudrate(hu, speed);
 
 error:
-		if (soc_type == QCA_WCN3990)
+		if (qca_is_wcn399x(soc_type))
 			hci_uart_set_flow_control(hu, false);
 	}
 
@@ -1201,7 +1201,7 @@  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);
 
-	if (soc_type == QCA_WCN3990) {
+	if (qca_is_wcn399x(soc_type)) {
 		bt_dev_info(hdev, "setting up wcn3990");
 
 		/* Enable NON_PERSISTENT_SETUP QUIRK to ensure to execute
@@ -1232,7 +1232,7 @@  static int qca_setup(struct hci_uart *hu)
 		qca_baudrate = qca_get_baudrate_value(speed);
 	}
 
-	if (soc_type != QCA_WCN3990) {
+	if (!qca_is_wcn399x(soc_type)) {
 		/* Get QCA version information */
 		ret = qca_read_soc_version(hdev, &soc_ver);
 		if (ret)
@@ -1257,7 +1257,7 @@  static int qca_setup(struct hci_uart *hu)
 	}
 
 	/* Setup bdaddr */
-	if (soc_type == QCA_WCN3990)
+	if (qca_is_wcn399x(soc_type))
 		hu->hdev->set_bdaddr = qca_set_bdaddr;
 	else
 		hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
@@ -1280,7 +1280,7 @@  static int qca_setup(struct hci_uart *hu)
 	.dequeue	= qca_dequeue,
 };
 
-static const struct qca_vreg_data qca_soc_data = {
+static const struct qca_vreg_data qca_soc_data_wcn3990 = {
 	.soc_type = QCA_WCN3990,
 	.vregs = (struct qca_vreg []) {
 		{ "vddio",   1800000, 1900000,  15000  },
@@ -1291,6 +1291,17 @@  static int qca_setup(struct hci_uart *hu)
 	.num_vregs = 4,
 };
 
+static const struct qca_vreg_data qca_soc_data_wcn3998 = {
+	.soc_type = QCA_WCN3998,
+	.vregs = (struct qca_vreg []) {
+		{ "vddio",   1800000, 1900000,  10000  },
+		{ "vddxo",   1800000, 1900000,  80000  },
+		{ "vddrf",   1300000, 1352000,  300000 },
+		{ "vddch0",  3300000, 3300000,  450000 },
+	},
+	.num_vregs = 4,
+};
+
 static void qca_power_shutdown(struct hci_uart *hu)
 {
 	struct qca_data *qca = hu->priv;
@@ -1424,8 +1435,8 @@  static int qca_serdev_probe(struct serdev_device *serdev)
 	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;
+	if (data && qca_is_wcn399x(data->soc_type)) {
+		qcadev->btsoc_type = data->soc_type;
 		qcadev->bt_power = devm_kzalloc(&serdev->dev,
 						sizeof(struct qca_power),
 						GFP_KERNEL);
@@ -1489,7 +1500,7 @@  static void qca_serdev_remove(struct serdev_device *serdev)
 {
 	struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
 
-	if (qcadev->btsoc_type == QCA_WCN3990)
+	if (qca_is_wcn399x(qcadev->btsoc_type))
 		qca_power_shutdown(&qcadev->serdev_hu);
 	else
 		clk_disable_unprepare(qcadev->susclk);
@@ -1499,7 +1510,8 @@  static void qca_serdev_remove(struct serdev_device *serdev)
 
 static const struct of_device_id qca_bluetooth_of_match[] = {
 	{ .compatible = "qcom,qca6174-bt" },
-	{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data},
+	{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990},
+	{ .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);