Commit 691d54d0 authored by Neil Armstrong's avatar Neil Armstrong Committed by Luiz Augusto von Dentz
Browse files

Bluetooth: qca: use switch case for soc type behavior



Use switch/case to handle soc type specific behaviour,
the permit dropping the qca_is_xxx() inline functions
and make the code clearer and easier to update for new
SoCs.

Suggested-by: default avatarKonrad Dybcio <konrad.dybcio@linaro.org>
Suggested-by: default avatarLuiz Augusto von Dentz <luiz.dentz@gmail.com>
Signed-off-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 9f19fb8f
Loading
Loading
Loading
Loading
+57 −30
Original line number Diff line number Diff line
@@ -604,26 +604,34 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,

	/* Download rampatch file */
	config.type = TLV_TYPE_PATCH;
	if (soc_type == QCA_WCN3988) {
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/apbtfw%02x.tlv", rom_ver);
	} else if (qca_is_wcn399x(soc_type)) {
	switch (soc_type) {
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/crbtfw%02x.tlv", rom_ver);
	} else if (soc_type == QCA_QCA6390) {
		break;
	case QCA_WCN3988:
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/apbtfw%02x.tlv", rom_ver);
		break;
	case QCA_QCA6390:
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/htbtfw%02x.tlv", rom_ver);
	} else if (soc_type == QCA_WCN6750) {
		break;
	case QCA_WCN6750:
		/* Choose mbn file by default.If mbn file is not found
		 * then choose tlv file
		 */
		config.type = ELF_TYPE_PATCH;
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/msbtfw%02x.mbn", rom_ver);
	} else if (soc_type == QCA_WCN6855) {
		break;
	case QCA_WCN6855:
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/hpbtfw%02x.tlv", rom_ver);
	} else {
		break;
	default:
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/rampatch_%08x.bin", soc_ver);
	}
@@ -639,13 +647,14 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,

	/* Download NVM configuration */
	config.type = TLV_TYPE_NVM;
	if (firmware_name)
	if (firmware_name) {
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/%s", firmware_name);
	else if (soc_type == QCA_WCN3988)
		snprintf(config.fwname, sizeof(config.fwname),
			 "qca/apnv%02x.bin", rom_ver);
	else if (qca_is_wcn399x(soc_type)) {
	} else {
		switch (soc_type) {
		case QCA_WCN3990:
		case QCA_WCN3991:
		case QCA_WCN3998:
			if (le32_to_cpu(ver.soc_id) == QCA_WCN3991_SOC_ID) {
				snprintf(config.fwname, sizeof(config.fwname),
					 "qca/crnv%02xu.bin", rom_ver);
@@ -653,19 +662,29 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
				snprintf(config.fwname, sizeof(config.fwname),
					 "qca/crnv%02x.bin", rom_ver);
			}
	}
	else if (soc_type == QCA_QCA6390)
			break;
		case QCA_WCN3988:
			snprintf(config.fwname, sizeof(config.fwname),
				 "qca/apnv%02x.bin", rom_ver);
			break;
		case QCA_QCA6390:
			snprintf(config.fwname, sizeof(config.fwname),
				 "qca/htnv%02x.bin", rom_ver);
	else if (soc_type == QCA_WCN6750)
			break;
		case QCA_WCN6750:
			snprintf(config.fwname, sizeof(config.fwname),
				 "qca/msnv%02x.bin", rom_ver);
	else if (soc_type == QCA_WCN6855)
			break;
		case QCA_WCN6855:
			snprintf(config.fwname, sizeof(config.fwname),
				 "qca/hpnv%02x.bin", rom_ver);
	else
			break;

		default:
			snprintf(config.fwname, sizeof(config.fwname),
				 "qca/nvm_%08x.bin", soc_ver);
		}
	}

	err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
	if (err < 0) {
@@ -673,16 +692,24 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
		return err;
	}

	if (soc_type >= QCA_WCN3991) {
	switch (soc_type) {
	case QCA_WCN3991:
	case QCA_QCA6390:
	case QCA_WCN6750:
	case QCA_WCN6855:
		err = qca_disable_soc_logging(hdev);
		if (err < 0)
			return err;
		break;
	default:
		break;
	}

	/* WCN399x and WCN6750 supports the Microsoft vendor extension with 0xFD70 as the
	 * VsMsftOpCode.
	 */
	switch (soc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
+0 −36
Original line number Diff line number Diff line
@@ -161,27 +161,6 @@ int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
			 enum qca_btsoc_type);
int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
int qca_send_pre_shutdown_cmd(struct hci_dev *hdev);
static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
{
	switch (soc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
		return true;
	default:
		return false;
	}
}
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

static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
@@ -209,21 +188,6 @@ 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;
}

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;
+179 −54
Original line number Diff line number Diff line
@@ -607,9 +607,18 @@ static int qca_open(struct hci_uart *hu)
	if (hu->serdev) {
		qcadev = serdev_device_get_drvdata(hu->serdev);

		if (qca_is_wcn399x(qcadev->btsoc_type) ||
		    qca_is_wcn6750(qcadev->btsoc_type))
		switch (qcadev->btsoc_type) {
		case QCA_WCN3988:
		case QCA_WCN3990:
		case QCA_WCN3991:
		case QCA_WCN3998:
		case QCA_WCN6750:
			hu->init_speed = qcadev->init_speed;
			break;

		default:
			break;
		}

		if (qcadev->oper_speed)
			hu->oper_speed = qcadev->oper_speed;
@@ -1341,12 +1350,19 @@ 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_is_wcn399x(qca_soc_type(hu)) ||
	    qca_is_wcn6750(qca_soc_type(hu)) ||
	    qca_is_wcn6855(qca_soc_type(hu)))
	switch (qca_soc_type(hu)) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
	case QCA_WCN6750:
	case QCA_WCN6855:
		usleep_range(1000, 10000);
	else
		break;

	default:
		msleep(300);
	}

	return 0;
}
@@ -1419,13 +1435,19 @@ 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_wcn6855(qca_soc_type(hu))) {
	switch (qca_soc_type(hu)) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
	case QCA_WCN6750:
	case QCA_WCN6855:
		if (!qca_get_speed(hu, QCA_INIT_SPEED) &&
		    !qca_get_speed(hu, QCA_OPER_SPEED))
			return -EINVAL;
	} else {
		break;

	default:
		if (!qca_get_speed(hu, QCA_INIT_SPEED) ||
		    !qca_get_speed(hu, QCA_OPER_SPEED))
			return -EINVAL;
@@ -1454,14 +1476,28 @@ 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 (qca_is_wcn399x(soc_type) ||
		    qca_is_wcn6750(soc_type) ||
		    qca_is_wcn6855(soc_type))
		switch (soc_type) {
		case QCA_WCN3988:
		case QCA_WCN3990:
		case QCA_WCN3991:
		case QCA_WCN3998:
		case QCA_WCN6750:
		case QCA_WCN6855:
			hci_uart_set_flow_control(hu, true);
			break;

		default:
			break;
		}

		if (soc_type == QCA_WCN3990) {
		switch (soc_type) {
		case QCA_WCN3990:
			reinit_completion(&qca->drop_ev_comp);
			set_bit(QCA_DROP_VENDOR_EVENT, &qca->flags);
			break;

		default:
			break;
		}

		qca_baudrate = qca_get_baudrate_value(speed);
@@ -1473,12 +1509,22 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
		host_set_baudrate(hu, speed);

error:
		if (qca_is_wcn399x(soc_type) ||
		    qca_is_wcn6750(soc_type) ||
		    qca_is_wcn6855(soc_type))
		switch (soc_type) {
		case QCA_WCN3988:
		case QCA_WCN3990:
		case QCA_WCN3991:
		case QCA_WCN3998:
		case QCA_WCN6750:
		case QCA_WCN6855:
			hci_uart_set_flow_control(hu, false);
			break;

		default:
			break;
		}

		if (soc_type == QCA_WCN3990) {
		switch (soc_type) {
		case QCA_WCN3990:
			/* Wait for the controller to send the vendor event
			 * for the baudrate change command.
			 */
@@ -1490,6 +1536,10 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
			}

			clear_bit(QCA_DROP_VENDOR_EVENT, &qca->flags);
			break;

		default:
			break;
		}
	}

@@ -1651,12 +1701,20 @@ static int qca_regulator_init(struct hci_uart *hu)
		}
	}

	if (qca_is_wcn399x(soc_type)) {
	switch (soc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
		/* Forcefully enable wcn399x to enter in to boot mode. */
		host_set_baudrate(hu, 2400);
		ret = qca_send_power_pulse(hu, false);
		if (ret)
			return ret;
		break;

	default:
		break;
	}

	/* For wcn6750 need to enable gpio bt_en */
@@ -1673,10 +1731,18 @@ static int qca_regulator_init(struct hci_uart *hu)

	qca_set_speed(hu, QCA_INIT_SPEED);

	if (qca_is_wcn399x(soc_type)) {
	switch (soc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
		ret = qca_send_power_pulse(hu, true);
		if (ret)
			return ret;
		break;

	default:
		break;
	}

	/* Now the device is in ready state to communicate with host.
@@ -1710,11 +1776,17 @@ static int qca_power_on(struct hci_dev *hdev)
	if (!hu->serdev)
		return 0;

	if (qca_is_wcn399x(soc_type) ||
	    qca_is_wcn6750(soc_type) ||
	    qca_is_wcn6855(soc_type)) {
	switch (soc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
	case QCA_WCN6750:
	case QCA_WCN6855:
		ret = qca_regulator_init(hu);
	} else {
		break;

	default:
		qcadev = serdev_device_get_drvdata(hu->serdev);
		if (qcadev->bt_en) {
			gpiod_set_value_cansleep(qcadev->bt_en, 1);
@@ -1748,6 +1820,7 @@ static int qca_setup(struct hci_uart *hu)
	const char *firmware_name = qca_get_firmware_name(hu);
	int ret;
	struct qca_btsoc_version ver;
	const char *soc_name;

	ret = qca_check_speeds(hu);
	if (ret)
@@ -1762,10 +1835,26 @@ static int qca_setup(struct hci_uart *hu)
	 */
	set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);

	bt_dev_info(hdev, "setting up %s",
		qca_is_wcn399x(soc_type) ? "wcn399x" :
		(soc_type == QCA_WCN6750) ? "wcn6750" :
		(soc_type == QCA_WCN6855) ? "wcn6855" : "ROME/QCA6390");
	switch (soc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
		soc_name = "wcn399x";
		break;

	case QCA_WCN6750:
		soc_name = "wcn6750";
		break;

	case QCA_WCN6855:
		soc_name = "wcn6855";
		break;

	default:
		soc_name = "ROME/QCA6390";
	}
	bt_dev_info(hdev, "setting up %s", soc_name);

	qca->memdump_state = QCA_MEMDUMP_IDLE;

@@ -1776,16 +1865,22 @@ 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_wcn6855(soc_type)) {
	switch (soc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
	case QCA_WCN6750:
	case QCA_WCN6855:
		set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
		hci_set_aosp_capable(hdev);

		ret = qca_read_soc_version(hdev, &ver, soc_type);
		if (ret)
			goto out;
	} else {
		break;

	default:
		qca_set_speed(hu, QCA_INIT_SPEED);
	}

@@ -1799,9 +1894,16 @@ static int qca_setup(struct hci_uart *hu)
		qca_baudrate = qca_get_baudrate_value(speed);
	}

	if (!(qca_is_wcn399x(soc_type) ||
	      qca_is_wcn6750(soc_type) ||
	      qca_is_wcn6855(soc_type))) {
	switch (soc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
	case QCA_WCN6750:
	case QCA_WCN6855:
		break;

	default:
		/* Get QCA version information */
		ret = qca_read_soc_version(hdev, &ver, soc_type);
		if (ret)
@@ -1980,11 +2082,18 @@ static void qca_power_shutdown(struct hci_uart *hu)

	qcadev = serdev_device_get_drvdata(hu->serdev);

	if (qca_is_wcn399x(soc_type)) {
	switch (soc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
		host_set_baudrate(hu, 2400);
		qca_send_power_pulse(hu, false);
		qca_regulator_disable(qcadev);
	} else if (soc_type == QCA_WCN6750 || soc_type == QCA_WCN6855) {
		break;

	case QCA_WCN6750:
	case QCA_WCN6855:
		gpiod_set_value_cansleep(qcadev->bt_en, 0);
		msleep(100);
		qca_regulator_disable(qcadev);
@@ -1992,7 +2101,9 @@ static void qca_power_shutdown(struct hci_uart *hu)
			sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl);
			bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state);
		}
	} else if (qcadev->bt_en) {
		break;

	default:
		gpiod_set_value_cansleep(qcadev->bt_en, 0);
	}

@@ -2117,11 +2228,18 @@ static int qca_serdev_probe(struct serdev_device *serdev)
	if (!qcadev->oper_speed)
		BT_DBG("UART will pick default operating speed");

	if (data &&
	    (qca_is_wcn399x(data->soc_type) ||
	     qca_is_wcn6750(data->soc_type) ||
	     qca_is_wcn6855(data->soc_type))) {
	if (data)
		qcadev->btsoc_type = data->soc_type;
	else
		qcadev->btsoc_type = QCA_ROME;

	switch (qcadev->btsoc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
	case QCA_WCN6750:
	case QCA_WCN6855:
		qcadev->bt_power = devm_kzalloc(&serdev->dev,
						sizeof(struct qca_power),
						GFP_KERNEL);
@@ -2165,12 +2283,9 @@ static int qca_serdev_probe(struct serdev_device *serdev)
			BT_ERR("wcn3990 serdev registration failed");
			return err;
		}
	} else {
		if (data)
			qcadev->btsoc_type = data->soc_type;
		else
			qcadev->btsoc_type = QCA_ROME;
		break;

	default:
		qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
					       GPIOD_OUT_LOW);
		if (IS_ERR_OR_NULL(qcadev->bt_en)) {
@@ -2226,13 +2341,23 @@ static void qca_serdev_remove(struct serdev_device *serdev)
	struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
	struct qca_power *power = qcadev->bt_power;

	if ((qca_is_wcn399x(qcadev->btsoc_type) ||
	     qca_is_wcn6750(qcadev->btsoc_type) ||
	     qca_is_wcn6855(qcadev->btsoc_type)) &&
	    power->vregs_on)
	switch (qcadev->btsoc_type) {
	case QCA_WCN3988:
	case QCA_WCN3990:
	case QCA_WCN3991:
	case QCA_WCN3998:
	case QCA_WCN6750:
	case QCA_WCN6855:
		if (power->vregs_on) {
			qca_power_shutdown(&qcadev->serdev_hu);
	else if (qcadev->susclk)
			break;
		}
		fallthrough;

	default:
		if (qcadev->susclk)
			clk_disable_unprepare(qcadev->susclk);
	}

	hci_uart_unregister_device(&qcadev->serdev_hu);
}