// SPDX-License-Identifier: GPL-2.0-only /* * Bluetooth Software UART Qualcomm protocol * * HCI_IBS (HCI In-Band Sleep) is Qualcomm's power management * protocol extension to H4. * * Copyright (C) 2007 Texas Instruments, Inc. * Copyright (c) 2010, 2012, 2018 The Linux Foundation. All rights reserved. * * Acknowledgements: * This file is based on hci_ll.c, which was... * Written by Ohad Ben-Cohen <ohad@bencohen.org> * which was in turn based on hci_h4.c, which was written * by Maxim Krasnyansky and Marcel Holtmann.
*/
/* * Platform data for the QCA Bluetooth power driver.
*/ struct qca_power { struct device *dev; struct regulator_bulk_data *vreg_bulk; int num_vregs; bool vregs_on; struct pwrseq_desc *pwrseq;
};
staticvoid __serial_clock_on(struct tty_struct *tty)
{ /* TODO: Some chipset requires to enable UART clock on client * side to save power consumption or manual work is required. * Please put your code to control UART clock here if needed
*/
}
staticvoid __serial_clock_off(struct tty_struct *tty)
{ /* TODO: Some chipset requires to disable UART clock on client * side to save power consumption or manual work is required. * Please put your code to control UART clock off here if needed
*/
}
/* serial_clock_vote needs to be called with the ibs lock held */ staticvoid serial_clock_vote(unsignedlong vote, struct hci_uart *hu)
{ struct qca_data *qca = hu->priv; unsignedint diff;
/* Always acknowledge device wake up, * sending IBS message doesn't count as TX ON.
*/ if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0)
BT_ERR("Failed to acknowledge device wake up");
/* Run HCI tx handling unlocked */
hci_uart_tx_wakeup(hu);
/* Now that message queued to tty driver, vote for tty clocks off. * It is up to the tty driver to pend the clocks off until tx done.
*/
serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
}
/* Assume we start with both sides asleep -- extra wakes OK */
qca->tx_ibs_state = HCI_IBS_TX_ASLEEP;
qca->rx_ibs_state = HCI_IBS_RX_ASLEEP;
qca->vote_last_jif = jiffies;
hu->priv = qca;
if (hu->serdev) {
qcadev = serdev_device_get_drvdata(hu->serdev);
switch (qcadev->btsoc_type) { case QCA_WCN3950: 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;
}
skb_queue_purge(&qca->tx_wait_q);
skb_queue_purge(&qca->txq);
skb_queue_purge(&qca->rx_memdump_q); /* * Shut the timers down so they can't be rearmed when * destroy_workqueue() drains pending work which in turn might try * to arm a timer. After shutdown rearm attempts are silently * ignored by the timer core code.
*/
timer_shutdown_sync(&qca->tx_idle_timer);
timer_shutdown_sync(&qca->wake_retrans_timer);
destroy_workqueue(qca->workqueue);
qca->hu = NULL;
kfree_skb(qca->rx_skb);
hu->priv = NULL;
kfree(qca);
return 0;
}
/* Called upon a wake-up-indication from the device.
*/ staticvoid device_want_to_wakeup(struct hci_uart *hu)
{ unsignedlong flags; struct qca_data *qca = hu->priv;
BT_DBG("hu %p want to wake up", hu);
spin_lock_irqsave(&qca->hci_ibs_lock, flags);
qca->ibs_recv_wakes++;
/* Don't wake the rx up when suspending. */ if (test_bit(QCA_SUSPENDING, &qca->flags)) {
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags); return;
}
switch (qca->rx_ibs_state) { case HCI_IBS_RX_ASLEEP: /* Make sure clock is on - we may have turned clock off since * receiving the wake up indicator awake rx clock.
*/
queue_work(qca->workqueue, &qca->ws_awake_rx);
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags); return;
case HCI_IBS_RX_AWAKE: /* Always acknowledge device wake up, * sending IBS message doesn't count as TX ON.
*/ if (send_hci_ibs_cmd(HCI_IBS_WAKE_ACK, hu) < 0) {
BT_ERR("Failed to acknowledge device wake up"); break;
}
qca->ibs_sent_wacks++; break;
default: /* Any other state is illegal */
BT_ERR("Received HCI_IBS_WAKE_IND in rx state %d",
qca->rx_ibs_state); break;
}
/* Actually send the packets */
hci_uart_tx_wakeup(hu);
}
/* Called upon a sleep-indication from the device.
*/ staticvoid device_want_to_sleep(struct hci_uart *hu)
{ unsignedlong flags; struct qca_data *qca = hu->priv;
BT_DBG("hu %p want to sleep in %d state", hu, qca->rx_ibs_state);
spin_lock_irqsave(&qca->hci_ibs_lock, flags);
qca->ibs_recv_slps++;
switch (qca->rx_ibs_state) { case HCI_IBS_RX_AWAKE: /* Update state */
qca->rx_ibs_state = HCI_IBS_RX_ASLEEP; /* Vote off rx clock under workqueue */
queue_work(qca->workqueue, &qca->ws_rx_vote_off); break;
case HCI_IBS_RX_ASLEEP: break;
default: /* Any other state is illegal */
BT_ERR("Received HCI_IBS_SLEEP_IND in rx state %d",
qca->rx_ibs_state); break;
}
/* Called upon wake-up-acknowledgement from the device
*/ staticvoid device_woke_up(struct hci_uart *hu)
{ unsignedlong flags, idle_delay; struct qca_data *qca = hu->priv; struct sk_buff *skb = NULL;
BT_DBG("hu %p woke up", hu);
spin_lock_irqsave(&qca->hci_ibs_lock, flags);
qca->ibs_recv_wacks++;
/* Don't react to the wake-up-acknowledgment when suspending. */ if (test_bit(QCA_SUSPENDING, &qca->flags)) {
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags); return;
}
switch (qca->tx_ibs_state) { case HCI_IBS_TX_AWAKE: /* Expect one if we send 2 WAKEs */
BT_DBG("Received HCI_IBS_WAKE_ACK in tx state %d",
qca->tx_ibs_state); break;
case HCI_IBS_TX_WAKING: /* Send pending packets */ while ((skb = skb_dequeue(&qca->tx_wait_q)))
skb_queue_tail(&qca->txq, skb);
/* Switch timers and change state to HCI_IBS_TX_AWAKE */
timer_delete(&qca->wake_retrans_timer);
idle_delay = msecs_to_jiffies(qca->tx_idle_delay);
mod_timer(&qca->tx_idle_timer, jiffies + idle_delay);
qca->tx_ibs_state = HCI_IBS_TX_AWAKE; break;
case HCI_IBS_TX_ASLEEP: default:
BT_ERR("Received HCI_IBS_WAKE_ACK in tx state %d",
qca->tx_ibs_state); break;
}
if (test_bit(QCA_SSR_TRIGGERED, &qca->flags)) { /* As SSR is in progress, ignore the packets */
bt_dev_dbg(hu->hdev, "SSR is in progress");
kfree_skb(skb); return 0;
}
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
spin_lock_irqsave(&qca->hci_ibs_lock, flags);
/* Don't go to sleep in middle of patch download or * Out-Of-Band(GPIOs control) sleep is selected. * Don't wake the device up when suspending.
*/ if (test_bit(QCA_IBS_DISABLED, &qca->flags) ||
test_bit(QCA_SUSPENDING, &qca->flags)) {
skb_queue_tail(&qca->txq, skb);
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags); return 0;
}
/* Act according to current state */ switch (qca->tx_ibs_state) { case HCI_IBS_TX_AWAKE:
BT_DBG("Device awake, sending normally");
skb_queue_tail(&qca->txq, skb);
idle_delay = msecs_to_jiffies(qca->tx_idle_delay);
mod_timer(&qca->tx_idle_timer, jiffies + idle_delay); break;
case HCI_IBS_TX_ASLEEP:
BT_DBG("Device asleep, waking up and queueing packet"); /* Save packet for later */
skb_queue_tail(&qca->tx_wait_q, skb);
qca->tx_ibs_state = HCI_IBS_TX_WAKING; /* Schedule a work queue to wake up device */
queue_work(qca->workqueue, &qca->ws_awake_device); break;
case HCI_IBS_TX_WAKING:
BT_DBG("Device waking up, queueing packet"); /* Transient state; just keep packet for later */
skb_queue_tail(&qca->tx_wait_q, skb); break;
staticint qca_recv_acl_data(struct hci_dev *hdev, struct sk_buff *skb)
{ /* We receive debug logs from chip as an ACL packets. * Instead of sending the data to ACL to decode the * received data, we are pushing them to the above layers * as a diagnostic packet.
*/ if (get_unaligned_le16(skb->data) == QCA_DEBUG_HANDLE) return hci_recv_diag(hdev, skb);
/* This is the first frame of memdump packet from * the controller, Disable IBS to receive dump * with out any interruption, ideally time required for * the controller to send the dump is 8 seconds. let us * start timer to handle this asynchronous activity.
*/
set_bit(QCA_IBS_DISABLED, &qca->flags);
set_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
dump = (void *) skb->data;
qca_memdump->ram_dump_size = __le32_to_cpu(dump->dump_size); if (!(qca_memdump->ram_dump_size)) {
bt_dev_err(hu->hdev, "Rx invalid memdump size");
kfree(qca_memdump);
kfree_skb(skb);
mutex_unlock(&qca->hci_memdump_lock); return;
}
bt_dev_info(hu->hdev, "QCA collecting dump of size:%u",
qca_memdump->ram_dump_size);
}
/* If sequence no 0 is missed then there is no point in * accepting the other sequences.
*/ if (!test_bit(QCA_MEMDUMP_COLLECTION, &qca->flags)) {
bt_dev_err(hu->hdev, "QCA: Discarding other packets");
kfree(qca_memdump);
kfree_skb(skb);
mutex_unlock(&qca->hci_memdump_lock); return;
} /* There could be chance of missing some packets from * the controller. In such cases let us store the dummy * packets in the buffer.
*/ /* For QCA6390, controller does not lost packets but * sequence number field of packet sometimes has error * bits, so skip this checking for missing packet.
*/ while ((seq_no > qca_memdump->current_seq_no + 1) &&
(soc_type != QCA_QCA6390) &&
seq_no != QCA_LAST_SEQUENCE_NUM) {
bt_dev_err(hu->hdev, "QCA controller missed packet:%d",
qca_memdump->current_seq_no);
rx_size = qca_memdump->received_dump;
rx_size += QCA_DUMP_PACKET_SIZE; if (rx_size > qca_memdump->ram_dump_size) {
bt_dev_err(hu->hdev, "QCA memdump received %d, no space for missed packet",
qca_memdump->received_dump); break;
}
hci_devcd_append_pattern(hu->hdev, 0x00,
QCA_DUMP_PACKET_SIZE);
qca_memdump->received_dump += QCA_DUMP_PACKET_SIZE;
qca_memdump->current_seq_no++;
}
rx_size = qca_memdump->received_dump + skb->len; if (rx_size <= qca_memdump->ram_dump_size) { if ((seq_no != QCA_LAST_SEQUENCE_NUM) &&
(seq_no != qca_memdump->current_seq_no)) {
bt_dev_err(hu->hdev, "QCA memdump unexpected packet %d",
seq_no);
}
bt_dev_dbg(hu->hdev, "QCA memdump packet %d with length %d",
seq_no, skb->len);
hci_devcd_append(hu->hdev, skb);
qca_memdump->current_seq_no += 1;
qca_memdump->received_dump = rx_size;
} else {
bt_dev_err(hu->hdev, "QCA memdump received no space for packet %d",
qca_memdump->current_seq_no);
}
if (seq_no == QCA_LAST_SEQUENCE_NUM) {
bt_dev_info(hu->hdev, "QCA memdump Done, received %d, total %d",
qca_memdump->received_dump,
qca_memdump->ram_dump_size);
hci_devcd_complete(hu->hdev);
cancel_delayed_work(&qca->ctrl_memdump_timeout);
kfree(qca->qca_memdump);
qca->qca_memdump = NULL;
qca->memdump_state = QCA_MEMDUMP_COLLECTED;
clear_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
}
if (test_bit(QCA_DROP_VENDOR_EVENT, &qca->flags)) { struct hci_event_hdr *hdr = (void *)skb->data;
/* For the WCN3990 the vendor command for a baudrate change * isn't sent as synchronous HCI command, because the * controller sends the corresponding vendor event with the * new baudrate. The event is received and properly decoded * after changing the baudrate of the host port. It needs to * be dropped, otherwise it can be misinterpreted as * response to a later firmware download command (also a * vendor command).
*/
if (hdr->evt == HCI_EV_VENDOR)
complete(&qca->drop_ev_comp);
kfree_skb(skb);
return 0;
} /* We receive chip memory dump as an event packet, With a dedicated * handler followed by a hardware error event. When this event is * received we store dump into a file before closing hci. This * dump will help in triaging the issues.
*/ if ((skb->data[0] == HCI_VENDOR_PKT) &&
(get_unaligned_be16(skb->data + 2) == QCA_SSR_DUMP_HANDLE)) return qca_controller_memdump_event(hdev, skb);
static uint8_t qca_get_baudrate_value(int speed)
{ switch (speed) { case 9600: return QCA_BAUDRATE_9600; case 19200: return QCA_BAUDRATE_19200; case 38400: return QCA_BAUDRATE_38400; case 57600: return QCA_BAUDRATE_57600; case 115200: return QCA_BAUDRATE_115200; case 230400: return QCA_BAUDRATE_230400; case 460800: return QCA_BAUDRATE_460800; case 500000: return QCA_BAUDRATE_500000; case 921600: return QCA_BAUDRATE_921600; case 1000000: return QCA_BAUDRATE_1000000; case 2000000: return QCA_BAUDRATE_2000000; case 3000000: return QCA_BAUDRATE_3000000; case 3200000: return QCA_BAUDRATE_3200000; case 3500000: return QCA_BAUDRATE_3500000; default: return QCA_BAUDRATE_115200;
}
}
/* Wait for the baudrate change request to be sent */
while (!skb_queue_empty(&qca->txq))
usleep_range(100, 200);
if (hu->serdev)
serdev_device_wait_until_sent(hu->serdev,
msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
/* Give the controller time to process the request */ switch (qca_soc_type(hu)) { case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850:
usleep_range(1000, 10000); break;
staticint qca_send_power_pulse(struct hci_uart *hu, bool on)
{ int ret; int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
u8 cmd = on ? QCA_WCN3990_POWERON_PULSE : QCA_WCN3990_POWEROFF_PULSE;
/* 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(hu->hdev, "sending power pulse %02x to controller", cmd);
serdev_device_write_flush(hu->serdev);
hci_uart_set_flow_control(hu, true);
ret = serdev_device_write_buf(hu->serdev, &cmd, sizeof(cmd)); if (ret < 0) {
bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd); return ret;
}
if (speed_type == QCA_INIT_SPEED) { if (hu->init_speed)
speed = hu->init_speed; elseif (hu->proto->init_speed)
speed = hu->proto->init_speed;
} else { if (hu->oper_speed)
speed = hu->oper_speed; elseif (hu->proto->oper_speed)
speed = hu->proto->oper_speed;
}
return speed;
}
staticint qca_check_speeds(struct hci_uart *hu)
{ switch (qca_soc_type(hu)) { case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: if (!qca_get_speed(hu, QCA_INIT_SPEED) &&
!qca_get_speed(hu, QCA_OPER_SPEED)) return -EINVAL; break;
default: if (!qca_get_speed(hu, QCA_INIT_SPEED) ||
!qca_get_speed(hu, QCA_OPER_SPEED)) return -EINVAL;
}
return 0;
}
staticint qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
{ unsignedint speed, qca_baudrate; struct qca_data *qca = hu->priv; int ret = 0;
speed = qca_get_speed(hu, QCA_OPER_SPEED); if (!speed) return 0;
/* Disable flow control for wcn3990 to deassert RTS while * changing the baudrate of chip and host.
*/ switch (soc_type) { case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850:
hci_uart_set_flow_control(hu, true); break;
default: break;
}
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);
bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
ret = qca_set_baudrate(hu->hdev, qca_baudrate); if (ret) goto error;
host_set_baudrate(hu, speed);
error: switch (soc_type) { case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850:
hci_uart_set_flow_control(hu, false); break;
default: break;
}
switch (soc_type) { case QCA_WCN3990: /* Wait for the controller to send the vendor event * for the baudrate change command.
*/ if (!wait_for_completion_timeout(&qca->drop_ev_comp,
msecs_to_jiffies(100))) {
bt_dev_err(hu->hdev, "Failed to change controller baudrate\n");
ret = -ETIMEDOUT;
}
skb = bt_skb_alloc(QCA_CRASHBYTE_PACKET_LEN, GFP_KERNEL); if (!skb) {
bt_dev_err(hu->hdev, "Failed to allocate memory for skb packet"); return -ENOMEM;
}
/* We forcefully crash the controller, by sending 0xfb byte for * 1024 times. We also might have chance of losing data, To be * on safer side we send 1096 bytes to the SoC.
*/
memset(skb_put(skb, QCA_CRASHBYTE_PACKET_LEN), QCA_MEMDUMP_BYTE,
QCA_CRASHBYTE_PACKET_LEN);
hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
bt_dev_info(hu->hdev, "crash the soc to collect controller dump");
skb_queue_tail(&qca->txq, skb);
hci_uart_tx_wakeup(hu);
if (qca->memdump_state == QCA_MEMDUMP_IDLE) { /* If hardware error event received for other than QCA * soc memory dump event, then we need to crash the SOC * and wait here for 8 seconds to get the dump packets. * This will block main thread to be on hold until we * collect dump.
*/
set_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
qca_send_crashbuffer(hu);
qca_wait_for_dump_collection(hdev);
} elseif (qca->memdump_state == QCA_MEMDUMP_COLLECTING) { /* Let us wait here until memory dump collected or * memory dump timer expired.
*/
bt_dev_info(hdev, "waiting for dump to complete");
qca_wait_for_dump_collection(hdev);
}
mutex_lock(&qca->hci_memdump_lock); if (qca->memdump_state != QCA_MEMDUMP_COLLECTED) {
bt_dev_err(hu->hdev, "clearing allocated memory due to memdump timeout");
hci_devcd_abort(hu->hdev); if (qca->qca_memdump) {
kfree(qca->qca_memdump);
qca->qca_memdump = NULL;
}
qca->memdump_state = QCA_MEMDUMP_TIMEOUT;
cancel_delayed_work(&qca->ctrl_memdump_timeout);
}
mutex_unlock(&qca->hci_memdump_lock);
/* BT SoC attached through the serial bus is handled by the serdev driver. * So we need to use the device handle of the serdev driver to get the * status of device may wakeup.
*/
wakeup = device_may_wakeup(&hu->serdev->ctrl->dev);
bt_dev_dbg(hu->hdev, "wakeup status : %d", wakeup);
return wakeup;
}
staticint qca_port_reopen(struct hci_uart *hu)
{ int ret;
/* 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;
}
/* Check for vregs status, may be hci down has turned * off the voltage regulator.
*/
qcadev = serdev_device_get_drvdata(hu->serdev);
if (!qcadev->bt_power->vregs_on) {
serdev_device_close(hu->serdev);
ret = qca_regulator_enable(qcadev); if (ret) return ret;
ret = serdev_device_open(hu->serdev); if (ret) {
bt_dev_err(hu->hdev, "failed to open port"); return ret;
}
}
switch (soc_type) { case QCA_WCN3950: 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 */ if (qcadev->bt_en) {
gpiod_set_value_cansleep(qcadev->bt_en, 0);
msleep(50);
gpiod_set_value_cansleep(qcadev->bt_en, 1);
msleep(50); if (qcadev->sw_ctrl) {
sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl);
bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state);
}
}
qca_set_speed(hu, QCA_INIT_SPEED);
switch (soc_type) { case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998:
ret = qca_send_power_pulse(hu, true); if (ret) return ret; break;
/* Non-serdev device usually is powered by external power * and don't need additional action in driver for power on
*/ if (!hu->serdev) return 0;
switch (soc_type) { case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: case QCA_QCA6390:
ret = qca_regulator_init(hu); break;
default:
qcadev = serdev_device_get_drvdata(hu->serdev); if (qcadev->bt_en) {
gpiod_set_value_cansleep(qcadev->bt_en, 1); /* Controller needs time to bootup. */
msleep(150);
}
}
staticint qca_get_data_path_id(struct hci_dev *hdev, __u8 *data_path_id)
{ /* QCA uses 1 as non-HCI data path id for HFP */
*data_path_id = 1; return 0;
}
staticint qca_configure_hfp_offload(struct hci_dev *hdev)
{
bt_dev_info(hdev, "HFP non-HCI data transport is supported");
hdev->get_data_path_id = qca_get_data_path_id; /* Do not need to send HCI_Configure_Data_Path to configure non-HCI * data transport path for QCA controllers, so set below field as NULL.
*/
hdev->get_codec_config_data = NULL; return 0;
}
clear_bit(QCA_ROM_FW, &qca->flags); /* Patch downloading has to be done without IBS mode */
set_bit(QCA_IBS_DISABLED, &qca->flags);
/* Enable controller to do both LE scan and BR/EDR inquiry * simultaneously.
*/
hci_set_quirk(hdev, HCI_QUIRK_SIMULTANEOUS_DISCOVERY);
switch (soc_type) { case QCA_QCA2066:
soc_name = "qca2066"; break;
case QCA_WCN3950: 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;
case QCA_WCN7850:
soc_name = "wcn7850"; break;
default:
soc_name = "ROME/QCA6390";
}
bt_dev_info(hdev, "setting up %s", soc_name);
qca->memdump_state = QCA_MEMDUMP_IDLE;
retry:
ret = qca_power_on(hdev); if (ret) goto out;
clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
switch (soc_type) { case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850:
qcadev = serdev_device_get_drvdata(hu->serdev); if (qcadev->bdaddr_property_broken)
hci_set_quirk(hdev, HCI_QUIRK_BDADDR_PROPERTY_BROKEN);
hci_set_aosp_capable(hdev);
ret = qca_read_soc_version(hdev, &ver, soc_type); if (ret) goto out; break;
default:
qca_set_speed(hu, QCA_INIT_SPEED);
}
/* Setup user speed if needed */
speed = qca_get_speed(hu, QCA_OPER_SPEED); if (speed) {
ret = qca_set_speed(hu, QCA_OPER_SPEED); if (ret) goto out;
qca_baudrate = qca_get_baudrate_value(speed);
}
switch (soc_type) { case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: break;
default: /* Get QCA version information */
ret = qca_read_soc_version(hdev, &ver, soc_type); if (ret) goto out;
}
/* Setup patch / NVM configurations */
ret = qca_uart_setup(hdev, qca_baudrate, soc_type, ver,
firmware_name, rampatch_name); if (!ret) {
clear_bit(QCA_IBS_DISABLED, &qca->flags);
qca_debugfs_init(hdev);
hu->hdev->hw_error = qca_hw_error;
hu->hdev->reset = qca_reset; if (hu->serdev) { if (device_can_wakeup(hu->serdev->ctrl->dev.parent))
hu->hdev->wakeup = qca_wakeup;
}
} elseif (ret == -ENOENT) { /* No patch/nvm-config found, run with original fw/config */
set_bit(QCA_ROM_FW, &qca->flags);
ret = 0;
} elseif (ret == -EAGAIN) { /* * Userspace firmware loader will return -EAGAIN in case no * patch/nvm-config is found, so run with original fw/config.
*/
set_bit(QCA_ROM_FW, &qca->flags);
ret = 0;
}
out: if (ret && retries < MAX_INIT_RETRIES) {
bt_dev_warn(hdev, "Retry BT power ON:%d", retries);
qca_power_shutdown(hu); if (hu->serdev) {
serdev_device_close(hu->serdev);
ret = serdev_device_open(hu->serdev); if (ret) {
bt_dev_err(hdev, "failed to open port"); return ret;
}
}
retries++; goto retry;
}
/* From this point we go into power off state. But serial port is * still open, stop queueing the IBS data and flush all the buffered * data in skb's.
*/
spin_lock_irqsave(&qca->hci_ibs_lock, flags);
set_bit(QCA_IBS_DISABLED, &qca->flags);
qca_flush(hu);
spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
/* Non-serdev device usually is powered by external power * and don't need additional action in driver for power down
*/ if (!hu->serdev) return;
qcadev = serdev_device_get_drvdata(hu->serdev);
power = qcadev->bt_power;
if (power && power->pwrseq) {
pwrseq_power_off(power->pwrseq);
set_bit(QCA_BT_OFF, &qca->flags); return;
}
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); break;
case QCA_WCN6750: case QCA_WCN6855:
gpiod_set_value_cansleep(qcadev->bt_en, 0);
msleep(100);
qca_regulator_disable(qcadev); if (qcadev->sw_ctrl) {
sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl);
bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state);
} break;
if (data)
qcadev->btsoc_type = data->soc_type; else
qcadev->btsoc_type = QCA_ROME;
switch (qcadev->btsoc_type) { case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: case QCA_QCA6390:
qcadev->bt_power = devm_kzalloc(&serdev->dev, sizeof(struct qca_power),
GFP_KERNEL); if (!qcadev->bt_power) return -ENOMEM; break; default: break;
}
switch (qcadev->btsoc_type) { case QCA_WCN6855: case QCA_WCN7850: case QCA_WCN6750: if (!device_property_present(&serdev->dev, "enable-gpios")) { /* * Backward compatibility with old DT sources. If the * node doesn't have the 'enable-gpios' property then * let's use the power sequencer. Otherwise, let's * drive everything ourselves.
*/
qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->dev, "bluetooth");
/* * Some modules have BT_EN enabled via a hardware pull-up, * meaning it is not defined in the DTS and is not controlled * through the power sequence. In such cases, fall through * to follow the legacy flow.
*/ if (IS_ERR(qcadev->bt_power->pwrseq))
qcadev->bt_power->pwrseq = NULL; else break;
}
fallthrough; case QCA_WCN3950: case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998:
qcadev->bt_power->dev = &serdev->dev;
err = qca_init_regulators(qcadev->bt_power, data->vregs,
data->num_vregs); if (err) {
BT_ERR("Failed to init regulators:%d", err); return err;
}
qcadev->bt_power->vregs_on = false;
qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
GPIOD_OUT_LOW); if (IS_ERR(qcadev->bt_en)) return dev_err_probe(&serdev->dev,
PTR_ERR(qcadev->bt_en), "failed to acquire BT_EN gpio\n");
if (power_ctrl_enabled) {
hci_set_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP);
hdev->shutdown = qca_power_off;
}
if (data) { /* Wideband speech support must be set per driver since it can't * be queried via hci. Same with the valid le states quirk.
*/ if (data->capabilities & QCA_CAP_WIDEBAND_SPEECH)
hci_set_quirk(hdev,
HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED);
if (!(data->capabilities & QCA_CAP_VALID_LE_STATES))
hci_set_quirk(hdev, HCI_QUIRK_BROKEN_LE_STATES);
}
switch (qcadev->btsoc_type) { case QCA_WCN3988: case QCA_WCN3990: case QCA_WCN3991: case QCA_WCN3998: case QCA_WCN6750: case QCA_WCN6855: case QCA_WCN7850: if (power->vregs_on)
qca_power_shutdown(&qcadev->serdev_hu); break; default: break;
}
if (qcadev->btsoc_type == QCA_QCA6390) { /* The purpose of sending the VSC is to reset SOC into a initial * state and the state will ensure next hdev->setup() success. * if HCI_QUIRK_NON_PERSISTENT_SETUP is set, it means that * hdev->setup() can do its job regardless of SoC state, so * don't need to send the VSC. * if HCI_SETUP is set, it means that hdev->setup() was never * invoked and the SOC is already in the initial state, so * don't also need to send the VSC.
*/ if (hci_test_quirk(hdev, HCI_QUIRK_NON_PERSISTENT_SETUP) ||
hci_dev_test_flag(hdev, HCI_SETUP)) return;
/* The serdev must be in open state when control logic arrives * here, so also fix the use-after-free issue caused by that * the serdev is flushed or wrote after it is closed.
*/
serdev_device_write_flush(serdev);
ret = serdev_device_write_buf(serdev, ibs_wake_cmd, sizeof(ibs_wake_cmd)); if (ret < 0) {
BT_ERR("QCA send IBS_WAKE_IND error: %d", ret); return;
}
serdev_device_wait_until_sent(serdev, timeout);
usleep_range(8000, 10000);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.