/*
 *  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.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/serdev.h>

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>

#include "hci_uart.h"
#include "btqca.h"

/* HCI_IBS protocol messages */
#define HCI_IBS_SLEEP_IND	0xFE
#define HCI_IBS_WAKE_IND	0xFD
#define HCI_IBS_WAKE_ACK	0xFC
#define HCI_MAX_IBS_SIZE	10

/* Controller states */
#define STATE_IN_BAND_SLEEP_ENABLED	1

#define IBS_WAKE_RETRANS_TIMEOUT_MS	100
#define IBS_TX_IDLE_TIMEOUT_MS		2000
#define BAUDRATE_SETTLE_TIMEOUT_MS	300

/* susclk rate */
#define SUSCLK_RATE_32KHZ	32768

/* HCI_IBS transmit side sleep protocol states */
enum tx_ibs_states {
	HCI_IBS_TX_ASLEEP,
	HCI_IBS_TX_WAKING,
	HCI_IBS_TX_AWAKE,
};

/* HCI_IBS receive side sleep protocol states */
enum rx_states {
	HCI_IBS_RX_ASLEEP,
	HCI_IBS_RX_AWAKE,
};

/* HCI_IBS transmit and receive side clock state vote */
enum hci_ibs_clock_state_vote {
	HCI_IBS_VOTE_STATS_UPDATE,
	HCI_IBS_TX_VOTE_CLOCK_ON,
	HCI_IBS_TX_VOTE_CLOCK_OFF,
	HCI_IBS_RX_VOTE_CLOCK_ON,
	HCI_IBS_RX_VOTE_CLOCK_OFF,
};

struct qca_data {
	struct hci_uart *hu;
	struct sk_buff *rx_skb;
	struct sk_buff_head txq;
	struct sk_buff_head tx_wait_q;	/* HCI_IBS wait queue	*/
	spinlock_t hci_ibs_lock;	/* HCI_IBS state lock	*/
	u8 tx_ibs_state;	/* HCI_IBS transmit side power state*/
	u8 rx_ibs_state;	/* HCI_IBS receive side power state */
	bool tx_vote;		/* Clock must be on for TX */
	bool rx_vote;		/* Clock must be on for RX */
	struct timer_list tx_idle_timer;
	u32 tx_idle_delay;
	struct timer_list wake_retrans_timer;
	u32 wake_retrans;
	struct workqueue_struct *workqueue;
	struct work_struct ws_awake_rx;
	struct work_struct ws_awake_device;
	struct work_struct ws_rx_vote_off;
	struct work_struct ws_tx_vote_off;
	unsigned long flags;

	/* For debugging purpose */
	u64 ibs_sent_wacks;
	u64 ibs_sent_slps;
	u64 ibs_sent_wakes;
	u64 ibs_recv_wacks;
	u64 ibs_recv_slps;
	u64 ibs_recv_wakes;
	u64 vote_last_jif;
	u32 vote_on_ms;
	u32 vote_off_ms;
	u64 tx_votes_on;
	u64 rx_votes_on;
	u64 tx_votes_off;
	u64 rx_votes_off;
	u64 votes_on;
	u64 votes_off;
};

enum qca_speed_type {
	QCA_INIT_SPEED = 1,
	QCA_OPER_SPEED
};

/*
 * Voltage regulator information required for configuring the
 * QCA Bluetooth chipset
 */
struct qca_vreg {
	const char *name;
	unsigned int min_uV;
	unsigned int max_uV;
	unsigned int load_uA;
};

struct qca_vreg_data {
	enum qca_btsoc_type soc_type;
	struct qca_vreg *vregs;
	size_t num_vregs;
};

/*
 * Platform data for the QCA Bluetooth power driver.
 */
struct qca_power {
	struct device *dev;
	const struct qca_vreg_data *vreg_data;
	struct regulator_bulk_data *vreg_bulk;
	bool vregs_on;
};

struct qca_serdev {
	struct hci_uart	 serdev_hu;
	struct gpio_desc *bt_en;
	struct clk	 *susclk;
	enum qca_btsoc_type btsoc_type;
	struct qca_power *bt_power;
	u32 init_speed;
	u32 oper_speed;
};

static int qca_power_setup(struct hci_uart *hu, bool on);
static void qca_power_shutdown(struct hci_dev *hdev);

static void __serial_clock_on(struct tty_struct *tty)
{
	/* TODO: Some chipset requires to enable UART clock on client
	 * side to save power consumption or manual work is required.
	 * Please put your code to control UART clock here if needed
	 */
}

static void __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 */
static void serial_clock_vote(unsigned long vote, struct hci_uart *hu)
{
	struct qca_data *qca = hu->priv;
	unsigned int diff;

	bool old_vote = (qca->tx_vote | qca->rx_vote);
	bool new_vote;

	switch (vote) {
	case HCI_IBS_VOTE_STATS_UPDATE:
		diff = jiffies_to_msecs(jiffies - qca->vote_last_jif);

		if (old_vote)
			qca->vote_off_ms += diff;
		else
			qca->vote_on_ms += diff;
		return;

	case HCI_IBS_TX_VOTE_CLOCK_ON:
		qca->tx_vote = true;
		qca->tx_votes_on++;
		new_vote = true;
		break;

	case HCI_IBS_RX_VOTE_CLOCK_ON:
		qca->rx_vote = true;
		qca->rx_votes_on++;
		new_vote = true;
		break;

	case HCI_IBS_TX_VOTE_CLOCK_OFF:
		qca->tx_vote = false;
		qca->tx_votes_off++;
		new_vote = qca->rx_vote | qca->tx_vote;
		break;

	case HCI_IBS_RX_VOTE_CLOCK_OFF:
		qca->rx_vote = false;
		qca->rx_votes_off++;
		new_vote = qca->rx_vote | qca->tx_vote;
		break;

	default:
		BT_ERR("Voting irregularity");
		return;
	}

	if (new_vote != old_vote) {
		if (new_vote)
			__serial_clock_on(hu->tty);
		else
			__serial_clock_off(hu->tty);

		BT_DBG("Vote serial clock %s(%s)", new_vote ? "true" : "false",
		       vote ? "true" : "false");

		diff = jiffies_to_msecs(jiffies - qca->vote_last_jif);

		if (new_vote) {
			qca->votes_on++;
			qca->vote_off_ms += diff;
		} else {
			qca->votes_off++;
			qca->vote_on_ms += diff;
		}
		qca->vote_last_jif = jiffies;
	}
}

/* Builds and sends an HCI_IBS command packet.
 * These are very simple packets with only 1 cmd byte.
 */
static int send_hci_ibs_cmd(u8 cmd, struct hci_uart *hu)
{
	int err = 0;
	struct sk_buff *skb = NULL;
	struct qca_data *qca = hu->priv;

	BT_DBG("hu %p send hci ibs cmd 0x%x", hu, cmd);

	skb = bt_skb_alloc(1, GFP_ATOMIC);
	if (!skb) {
		BT_ERR("Failed to allocate memory for HCI_IBS packet");
		return -ENOMEM;
	}

	/* Assign HCI_IBS type */
	skb_put_u8(skb, cmd);

	skb_queue_tail(&qca->txq, skb);

	return err;
}

static void qca_wq_awake_device(struct work_struct *work)
{
	struct qca_data *qca = container_of(work, struct qca_data,
					    ws_awake_device);
	struct hci_uart *hu = qca->hu;
	unsigned long retrans_delay;

	BT_DBG("hu %p wq awake device", hu);

	/* Vote for serial clock */
	serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu);

	spin_lock(&qca->hci_ibs_lock);

	/* Send wake indication to device */
	if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0)
		BT_ERR("Failed to send WAKE to device");

	qca->ibs_sent_wakes++;

	/* Start retransmit timer */
	retrans_delay = msecs_to_jiffies(qca->wake_retrans);
	mod_timer(&qca->wake_retrans_timer, jiffies + retrans_delay);

	spin_unlock(&qca->hci_ibs_lock);

	/* Actually send the packets */
	hci_uart_tx_wakeup(hu);
}

static void qca_wq_awake_rx(struct work_struct *work)
{
	struct qca_data *qca = container_of(work, struct qca_data,
					    ws_awake_rx);
	struct hci_uart *hu = qca->hu;

	BT_DBG("hu %p wq awake rx", hu);

	serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);

	spin_lock(&qca->hci_ibs_lock);
	qca->rx_ibs_state = 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");

	qca->ibs_sent_wacks++;

	spin_unlock(&qca->hci_ibs_lock);

	/* Actually send the packets */
	hci_uart_tx_wakeup(hu);
}

static void qca_wq_serial_rx_clock_vote_off(struct work_struct *work)
{
	struct qca_data *qca = container_of(work, struct qca_data,
					    ws_rx_vote_off);
	struct hci_uart *hu = qca->hu;

	BT_DBG("hu %p rx clock vote off", hu);

	serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_OFF, hu);
}

static void qca_wq_serial_tx_clock_vote_off(struct work_struct *work)
{
	struct qca_data *qca = container_of(work, struct qca_data,
					    ws_tx_vote_off);
	struct hci_uart *hu = qca->hu;

	BT_DBG("hu %p tx clock vote off", hu);

	/* 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);
}

static void hci_ibs_tx_idle_timeout(struct timer_list *t)
{
	struct qca_data *qca = from_timer(qca, t, tx_idle_timer);
	struct hci_uart *hu = qca->hu;
	unsigned long flags;

	BT_DBG("hu %p idle timeout in %d state", hu, qca->tx_ibs_state);

	spin_lock_irqsave_nested(&qca->hci_ibs_lock,
				 flags, SINGLE_DEPTH_NESTING);

	switch (qca->tx_ibs_state) {
	case HCI_IBS_TX_AWAKE:
		/* TX_IDLE, go to SLEEP */
		if (send_hci_ibs_cmd(HCI_IBS_SLEEP_IND, hu) < 0) {
			BT_ERR("Failed to send SLEEP to device");
			break;
		}
		qca->tx_ibs_state = HCI_IBS_TX_ASLEEP;
		qca->ibs_sent_slps++;
		queue_work(qca->workqueue, &qca->ws_tx_vote_off);
		break;

	case HCI_IBS_TX_ASLEEP:
	case HCI_IBS_TX_WAKING:
		/* Fall through */

	default:
		BT_ERR("Spurious timeout tx state %d", qca->tx_ibs_state);
		break;
	}

	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
}

static void hci_ibs_wake_retrans_timeout(struct timer_list *t)
{
	struct qca_data *qca = from_timer(qca, t, wake_retrans_timer);
	struct hci_uart *hu = qca->hu;
	unsigned long flags, retrans_delay;
	bool retransmit = false;

	BT_DBG("hu %p wake retransmit timeout in %d state",
		hu, qca->tx_ibs_state);

	spin_lock_irqsave_nested(&qca->hci_ibs_lock,
				 flags, SINGLE_DEPTH_NESTING);

	switch (qca->tx_ibs_state) {
	case HCI_IBS_TX_WAKING:
		/* No WAKE_ACK, retransmit WAKE */
		retransmit = true;
		if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0) {
			BT_ERR("Failed to acknowledge device wake up");
			break;
		}
		qca->ibs_sent_wakes++;
		retrans_delay = msecs_to_jiffies(qca->wake_retrans);
		mod_timer(&qca->wake_retrans_timer, jiffies + retrans_delay);
		break;

	case HCI_IBS_TX_ASLEEP:
	case HCI_IBS_TX_AWAKE:
		/* Fall through */

	default:
		BT_ERR("Spurious timeout tx state %d", qca->tx_ibs_state);
		break;
	}

	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);

	if (retransmit)
		hci_uart_tx_wakeup(hu);
}

/* Initialize protocol */
static int qca_open(struct hci_uart *hu)
{
	struct qca_serdev *qcadev;
	struct qca_data *qca;
	int ret;

	BT_DBG("hu %p qca_open", hu);

	qca = kzalloc(sizeof(struct qca_data), GFP_KERNEL);
	if (!qca)
		return -ENOMEM;

	skb_queue_head_init(&qca->txq);
	skb_queue_head_init(&qca->tx_wait_q);
	spin_lock_init(&qca->hci_ibs_lock);
	qca->workqueue = alloc_ordered_workqueue("qca_wq", 0);
	if (!qca->workqueue) {
		BT_ERR("QCA Workqueue not initialized properly");
		kfree(qca);
		return -ENOMEM;
	}

	INIT_WORK(&qca->ws_awake_rx, qca_wq_awake_rx);
	INIT_WORK(&qca->ws_awake_device, qca_wq_awake_device);
	INIT_WORK(&qca->ws_rx_vote_off, qca_wq_serial_rx_clock_vote_off);
	INIT_WORK(&qca->ws_tx_vote_off, qca_wq_serial_tx_clock_vote_off);

	qca->hu = 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;

	/* clocks actually on, but we start votes off */
	qca->tx_vote = false;
	qca->rx_vote = false;
	qca->flags = 0;

	qca->ibs_sent_wacks = 0;
	qca->ibs_sent_slps = 0;
	qca->ibs_sent_wakes = 0;
	qca->ibs_recv_wacks = 0;
	qca->ibs_recv_slps = 0;
	qca->ibs_recv_wakes = 0;
	qca->vote_last_jif = jiffies;
	qca->vote_on_ms = 0;
	qca->vote_off_ms = 0;
	qca->votes_on = 0;
	qca->votes_off = 0;
	qca->tx_votes_on = 0;
	qca->tx_votes_off = 0;
	qca->rx_votes_on = 0;
	qca->rx_votes_off = 0;

	hu->priv = qca;

	if (hu->serdev) {
		serdev_device_open(hu->serdev);

		qcadev = serdev_device_get_drvdata(hu->serdev);
		if (qcadev->btsoc_type != QCA_WCN3990) {
			gpiod_set_value_cansleep(qcadev->bt_en, 1);
		} else {
			hu->init_speed = qcadev->init_speed;
			hu->oper_speed = qcadev->oper_speed;
			ret = qca_power_setup(hu, true);
			if (ret) {
				destroy_workqueue(qca->workqueue);
				kfree_skb(qca->rx_skb);
				hu->priv = NULL;
				kfree(qca);
				return ret;
			}
		}
	}

	timer_setup(&qca->wake_retrans_timer, hci_ibs_wake_retrans_timeout, 0);
	qca->wake_retrans = IBS_WAKE_RETRANS_TIMEOUT_MS;

	timer_setup(&qca->tx_idle_timer, hci_ibs_tx_idle_timeout, 0);
	qca->tx_idle_delay = IBS_TX_IDLE_TIMEOUT_MS;

	BT_DBG("HCI_UART_QCA open, tx_idle_delay=%u, wake_retrans=%u",
	       qca->tx_idle_delay, qca->wake_retrans);

	return 0;
}

static void qca_debugfs_init(struct hci_dev *hdev)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);
	struct qca_data *qca = hu->priv;
	struct dentry *ibs_dir;
	umode_t mode;

	if (!hdev->debugfs)
		return;

	ibs_dir = debugfs_create_dir("ibs", hdev->debugfs);

	/* read only */
	mode = S_IRUGO;
	debugfs_create_u8("tx_ibs_state", mode, ibs_dir, &qca->tx_ibs_state);
	debugfs_create_u8("rx_ibs_state", mode, ibs_dir, &qca->rx_ibs_state);
	debugfs_create_u64("ibs_sent_sleeps", mode, ibs_dir,
			   &qca->ibs_sent_slps);
	debugfs_create_u64("ibs_sent_wakes", mode, ibs_dir,
			   &qca->ibs_sent_wakes);
	debugfs_create_u64("ibs_sent_wake_acks", mode, ibs_dir,
			   &qca->ibs_sent_wacks);
	debugfs_create_u64("ibs_recv_sleeps", mode, ibs_dir,
			   &qca->ibs_recv_slps);
	debugfs_create_u64("ibs_recv_wakes", mode, ibs_dir,
			   &qca->ibs_recv_wakes);
	debugfs_create_u64("ibs_recv_wake_acks", mode, ibs_dir,
			   &qca->ibs_recv_wacks);
	debugfs_create_bool("tx_vote", mode, ibs_dir, &qca->tx_vote);
	debugfs_create_u64("tx_votes_on", mode, ibs_dir, &qca->tx_votes_on);
	debugfs_create_u64("tx_votes_off", mode, ibs_dir, &qca->tx_votes_off);
	debugfs_create_bool("rx_vote", mode, ibs_dir, &qca->rx_vote);
	debugfs_create_u64("rx_votes_on", mode, ibs_dir, &qca->rx_votes_on);
	debugfs_create_u64("rx_votes_off", mode, ibs_dir, &qca->rx_votes_off);
	debugfs_create_u64("votes_on", mode, ibs_dir, &qca->votes_on);
	debugfs_create_u64("votes_off", mode, ibs_dir, &qca->votes_off);
	debugfs_create_u32("vote_on_ms", mode, ibs_dir, &qca->vote_on_ms);
	debugfs_create_u32("vote_off_ms", mode, ibs_dir, &qca->vote_off_ms);

	/* read/write */
	mode = S_IRUGO | S_IWUSR;
	debugfs_create_u32("wake_retrans", mode, ibs_dir, &qca->wake_retrans);
	debugfs_create_u32("tx_idle_delay", mode, ibs_dir,
			   &qca->tx_idle_delay);
}

/* Flush protocol data */
static int qca_flush(struct hci_uart *hu)
{
	struct qca_data *qca = hu->priv;

	BT_DBG("hu %p qca flush", hu);

	skb_queue_purge(&qca->tx_wait_q);
	skb_queue_purge(&qca->txq);

	return 0;
}

/* Close protocol */
static int qca_close(struct hci_uart *hu)
{
	struct qca_serdev *qcadev;
	struct qca_data *qca = hu->priv;

	BT_DBG("hu %p qca close", hu);

	serial_clock_vote(HCI_IBS_VOTE_STATS_UPDATE, hu);

	skb_queue_purge(&qca->tx_wait_q);
	skb_queue_purge(&qca->txq);
	del_timer(&qca->tx_idle_timer);
	del_timer(&qca->wake_retrans_timer);
	destroy_workqueue(qca->workqueue);
	qca->hu = NULL;

	if (hu->serdev) {
		qcadev = serdev_device_get_drvdata(hu->serdev);
		if (qcadev->btsoc_type == QCA_WCN3990)
			qca_power_shutdown(hu->hdev);
		else
			gpiod_set_value_cansleep(qcadev->bt_en, 0);

		serdev_device_close(hu->serdev);
	}

	kfree_skb(qca->rx_skb);

	hu->priv = NULL;

	kfree(qca);

	return 0;
}

/* Called upon a wake-up-indication from the device.
 */
static void device_want_to_wakeup(struct hci_uart *hu)
{
	unsigned long 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++;

	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;
	}

	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);

	/* Actually send the packets */
	hci_uart_tx_wakeup(hu);
}

/* Called upon a sleep-indication from the device.
 */
static void device_want_to_sleep(struct hci_uart *hu)
{
	unsigned long flags;
	struct qca_data *qca = hu->priv;

	BT_DBG("hu %p want to sleep", hu);

	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:
		/* Fall through */

	default:
		/* Any other state is illegal */
		BT_ERR("Received HCI_IBS_SLEEP_IND in rx state %d",
		       qca->rx_ibs_state);
		break;
	}

	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
}

/* Called upon wake-up-acknowledgement from the device
 */
static void device_woke_up(struct hci_uart *hu)
{
	unsigned long 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++;

	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 */
		del_timer(&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:
		/* Fall through */

	default:
		BT_ERR("Received HCI_IBS_WAKE_ACK in tx state %d",
		       qca->tx_ibs_state);
		break;
	}

	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);

	/* Actually send the packets */
	hci_uart_tx_wakeup(hu);
}

/* Enqueue frame for transmittion (padding, crc, etc) may be called from
 * two simultaneous tasklets.
 */
static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
{
	unsigned long flags = 0, idle_delay;
	struct qca_data *qca = hu->priv;

	BT_DBG("hu %p qca enq skb %p tx_ibs_state %d", hu, skb,
	       qca->tx_ibs_state);

	/* Prepend skb with frame type */
	memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);

	/* Don't go to sleep in middle of patch download or
	 * Out-Of-Band(GPIOs control) sleep is selected.
	 */
	if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags)) {
		skb_queue_tail(&qca->txq, skb);
		return 0;
	}

	spin_lock_irqsave(&qca->hci_ibs_lock, flags);

	/* 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;

	default:
		BT_ERR("Illegal tx state: %d (losing packet)",
		       qca->tx_ibs_state);
		kfree_skb(skb);
		break;
	}

	spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);

	return 0;
}

static int qca_ibs_sleep_ind(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);

	BT_DBG("hu %p recv hci ibs cmd 0x%x", hu, HCI_IBS_SLEEP_IND);

	device_want_to_sleep(hu);

	kfree_skb(skb);
	return 0;
}

static int qca_ibs_wake_ind(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);

	BT_DBG("hu %p recv hci ibs cmd 0x%x", hu, HCI_IBS_WAKE_IND);

	device_want_to_wakeup(hu);

	kfree_skb(skb);
	return 0;
}

static int qca_ibs_wake_ack(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);

	BT_DBG("hu %p recv hci ibs cmd 0x%x", hu, HCI_IBS_WAKE_ACK);

	device_woke_up(hu);

	kfree_skb(skb);
	return 0;
}

#define QCA_IBS_SLEEP_IND_EVENT \
	.type = HCI_IBS_SLEEP_IND, \
	.hlen = 0, \
	.loff = 0, \
	.lsize = 0, \
	.maxlen = HCI_MAX_IBS_SIZE

#define QCA_IBS_WAKE_IND_EVENT \
	.type = HCI_IBS_WAKE_IND, \
	.hlen = 0, \
	.loff = 0, \
	.lsize = 0, \
	.maxlen = HCI_MAX_IBS_SIZE

#define QCA_IBS_WAKE_ACK_EVENT \
	.type = HCI_IBS_WAKE_ACK, \
	.hlen = 0, \
	.loff = 0, \
	.lsize = 0, \
	.maxlen = HCI_MAX_IBS_SIZE

static const struct h4_recv_pkt qca_recv_pkts[] = {
	{ H4_RECV_ACL,             .recv = hci_recv_frame    },
	{ H4_RECV_SCO,             .recv = hci_recv_frame    },
	{ H4_RECV_EVENT,           .recv = hci_recv_frame    },
	{ QCA_IBS_WAKE_IND_EVENT,  .recv = qca_ibs_wake_ind  },
	{ QCA_IBS_WAKE_ACK_EVENT,  .recv = qca_ibs_wake_ack  },
	{ QCA_IBS_SLEEP_IND_EVENT, .recv = qca_ibs_sleep_ind },
};

static int qca_recv(struct hci_uart *hu, const void *data, int count)
{
	struct qca_data *qca = hu->priv;

	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))
		return -EUNATCH;

	qca->rx_skb = h4_recv_buf(hu->hdev, qca->rx_skb, data, count,
				  qca_recv_pkts, ARRAY_SIZE(qca_recv_pkts));
	if (IS_ERR(qca->rx_skb)) {
		int err = PTR_ERR(qca->rx_skb);
		bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
		qca->rx_skb = NULL;
		return err;
	}

	return count;
}

static struct sk_buff *qca_dequeue(struct hci_uart *hu)
{
	struct qca_data *qca = hu->priv;

	return skb_dequeue(&qca->txq);
}

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;
	}
}

static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);
	struct qca_data *qca = hu->priv;
	struct sk_buff *skb;
	struct qca_serdev *qcadev;
	u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };

	if (baudrate > QCA_BAUDRATE_3200000)
		return -EINVAL;

	cmd[4] = baudrate;

	skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
	if (!skb) {
		bt_dev_err(hdev, "Failed to allocate baudrate packet");
		return -ENOMEM;
	}

	/* Disabling hardware flow control is mandatory while
	 * sending change baudrate request to wcn3990 SoC.
	 */
	qcadev = serdev_device_get_drvdata(hu->serdev);
	if (qcadev->btsoc_type == QCA_WCN3990)
		hci_uart_set_flow_control(hu, true);

	/* Assign commands to change baudrate and packet type. */
	skb_put_data(skb, cmd, sizeof(cmd));
	hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;

	skb_queue_tail(&qca->txq, skb);
	hci_uart_tx_wakeup(hu);

	/* wait 300ms to change new baudrate on controller side
	 * controller will come back after they receive this HCI command
	 * then host can communicate with new baudrate to controller
	 */
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
	set_current_state(TASK_RUNNING);

	if (qcadev->btsoc_type == QCA_WCN3990)
		hci_uart_set_flow_control(hu, false);

	return 0;
}

static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed)
{
	if (hu->serdev)
		serdev_device_set_baudrate(hu->serdev, speed);
	else
		hci_uart_set_baudrate(hu, speed);
}

static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);
	struct qca_data *qca = hu->priv;
	struct sk_buff *skb;

	/* These power pulses are single byte command which are sent
	 * at required baudrate to wcn3990. On wcn3990, we have an external
	 * circuit at Tx pin which decodes the pulse sent at specific baudrate.
	 * For example, wcn3990 supports RF COEX antenna for both Wi-Fi/BT
	 * and also we use the same power inputs to turn on and off for
	 * Wi-Fi/BT. Powering up the power sources will not enable BT, until
	 * we send a power on pulse at 115200 bps. This algorithm will help to
	 * save power. Disabling hardware flow control is mandatory while
	 * sending power pulses to SoC.
	 */
	bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);

	skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	hci_uart_set_flow_control(hu, true);

	skb_put_u8(skb, cmd);
	hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;

	skb_queue_tail(&qca->txq, skb);
	hci_uart_tx_wakeup(hu);

	/* Wait for 100 uS for SoC to settle down */
	usleep_range(100, 200);
	hci_uart_set_flow_control(hu, false);

	return 0;
}

static unsigned int qca_get_speed(struct hci_uart *hu,
				  enum qca_speed_type speed_type)
{
	unsigned int speed = 0;

	if (speed_type == QCA_INIT_SPEED) {
		if (hu->init_speed)
			speed = hu->init_speed;
		else if (hu->proto->init_speed)
			speed = hu->proto->init_speed;
	} else {
		if (hu->oper_speed)
			speed = hu->oper_speed;
		else if (hu->proto->oper_speed)
			speed = hu->proto->oper_speed;
	}

	return speed;
}

static int qca_check_speeds(struct hci_uart *hu)
{
	struct qca_serdev *qcadev;

	qcadev = serdev_device_get_drvdata(hu->serdev);
	if (qcadev->btsoc_type == QCA_WCN3990) {
		if (!qca_get_speed(hu, QCA_INIT_SPEED) &&
		    !qca_get_speed(hu, QCA_OPER_SPEED))
			return -EINVAL;
	} else {
		if (!qca_get_speed(hu, QCA_INIT_SPEED) ||
		    !qca_get_speed(hu, QCA_OPER_SPEED))
			return -EINVAL;
	}

	return 0;
}

static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
{
	unsigned int speed, qca_baudrate;
	int ret;

	if (speed_type == QCA_INIT_SPEED) {
		speed = qca_get_speed(hu, QCA_INIT_SPEED);
		if (speed)
			host_set_baudrate(hu, speed);
	} else {
		speed = qca_get_speed(hu, QCA_OPER_SPEED);
		if (!speed)
			return 0;

		qca_baudrate = qca_get_baudrate_value(speed);
		bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
		ret = qca_set_baudrate(hu->hdev, qca_baudrate);
		if (ret)
			return ret;

		host_set_baudrate(hu, speed);
	}

	return 0;
}

static int qca_wcn3990_init(struct hci_uart *hu)
{
	struct hci_dev *hdev = hu->hdev;
	int ret;

	/* Forcefully enable wcn3990 to enter in to boot mode. */
	host_set_baudrate(hu, 2400);
	ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
	if (ret)
		return ret;

	qca_set_speed(hu, QCA_INIT_SPEED);
	ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWERON_PULSE);
	if (ret)
		return ret;

	/* Wait for 100 ms for SoC to boot */
	msleep(100);

	/* Now the device is in ready state to communicate with host.
	 * To sync host with device we need to reopen port.
	 * Without this, we will have RTS and CTS synchronization
	 * issues.
	 */
	serdev_device_close(hu->serdev);
	ret = serdev_device_open(hu->serdev);
	if (ret) {
		bt_dev_err(hu->hdev, "failed to open port");
		return ret;
	}

	hci_uart_set_flow_control(hu, false);

	return 0;
}

static int qca_setup(struct hci_uart *hu)
{
	struct hci_dev *hdev = hu->hdev;
	struct qca_data *qca = hu->priv;
	unsigned int speed, qca_baudrate = QCA_BAUDRATE_115200;
	struct qca_serdev *qcadev;
	int ret;
	int soc_ver = 0;

	qcadev = serdev_device_get_drvdata(hu->serdev);

	ret = qca_check_speeds(hu);
	if (ret)
		return ret;

	/* Patch downloading has to be done without IBS mode */
	clear_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags);

	if (qcadev->btsoc_type == QCA_WCN3990) {
		bt_dev_info(hdev, "setting up wcn3990");
		ret = qca_wcn3990_init(hu);
		if (ret)
			return ret;

		ret = qca_read_soc_version(hdev, &soc_ver);
		if (ret)
			return ret;
	} else {
		bt_dev_info(hdev, "ROME setup");
		qca_set_speed(hu, QCA_INIT_SPEED);
	}

	/* Setup user speed if needed */
	speed = qca_get_speed(hu, QCA_OPER_SPEED);
	if (speed) {
		ret = qca_set_speed(hu, QCA_OPER_SPEED);
		if (ret)
			return ret;

		qca_baudrate = qca_get_baudrate_value(speed);
	}

	if (qcadev->btsoc_type != QCA_WCN3990) {
		/* Get QCA version information */
		ret = qca_read_soc_version(hdev, &soc_ver);
		if (ret)
			return ret;
	}

	bt_dev_info(hdev, "QCA controller version 0x%08x", soc_ver);
	/* Setup patch / NVM configurations */
	ret = qca_uart_setup(hdev, qca_baudrate, qcadev->btsoc_type, soc_ver);
	if (!ret) {
		set_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags);
		qca_debugfs_init(hdev);
	} else if (ret == -ENOENT) {
		/* No patch/nvm-config found, run with original fw/config */
		ret = 0;
	} else if (ret == -EAGAIN) {
		/*
		 * Userspace firmware loader will return -EAGAIN in case no
		 * patch/nvm-config is found, so run with original fw/config.
		 */
		ret = 0;
	}

	/* Setup bdaddr */
	hu->hdev->set_bdaddr = qca_set_bdaddr_rome;

	return ret;
}

static struct hci_uart_proto qca_proto = {
	.id		= HCI_UART_QCA,
	.name		= "QCA",
	.manufacturer	= 29,
	.init_speed	= 115200,
	.oper_speed	= 3000000,
	.open		= qca_open,
	.close		= qca_close,
	.flush		= qca_flush,
	.setup		= qca_setup,
	.recv		= qca_recv,
	.enqueue	= qca_enqueue,
	.dequeue	= qca_dequeue,
};

static const struct qca_vreg_data qca_soc_data = {
	.soc_type = QCA_WCN3990,
	.vregs = (struct qca_vreg []) {
		{ "vddio",   1800000, 1900000,  15000  },
		{ "vddxo",   1800000, 1900000,  80000  },
		{ "vddrf",   1300000, 1350000,  300000 },
		{ "vddch0",  3300000, 3400000,  450000 },
	},
	.num_vregs = 4,
};

static void qca_power_shutdown(struct hci_dev *hdev)
{
	struct hci_uart *hu = hci_get_drvdata(hdev);

	host_set_baudrate(hu, 2400);
	qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
	qca_power_setup(hu, false);
}

static int qca_enable_regulator(struct qca_vreg vregs,
				struct regulator *regulator)
{
	int ret;

	ret = regulator_set_voltage(regulator, vregs.min_uV,
				    vregs.max_uV);
	if (ret)
		return ret;

	if (vregs.load_uA)
		ret = regulator_set_load(regulator,
					 vregs.load_uA);

	if (ret)
		return ret;

	return regulator_enable(regulator);

}

static void qca_disable_regulator(struct qca_vreg vregs,
				  struct regulator *regulator)
{
	regulator_disable(regulator);
	regulator_set_voltage(regulator, 0, vregs.max_uV);
	if (vregs.load_uA)
		regulator_set_load(regulator, 0);

}

static int qca_power_setup(struct hci_uart *hu, bool on)
{
	struct qca_vreg *vregs;
	struct regulator_bulk_data *vreg_bulk;
	struct qca_serdev *qcadev;
	int i, num_vregs, ret = 0;

	qcadev = serdev_device_get_drvdata(hu->serdev);
	if (!qcadev || !qcadev->bt_power || !qcadev->bt_power->vreg_data ||
	    !qcadev->bt_power->vreg_bulk)
		return -EINVAL;

	vregs = qcadev->bt_power->vreg_data->vregs;
	vreg_bulk = qcadev->bt_power->vreg_bulk;
	num_vregs = qcadev->bt_power->vreg_data->num_vregs;
	BT_DBG("on: %d", on);
	if (on && !qcadev->bt_power->vregs_on) {
		for (i = 0; i < num_vregs; i++) {
			ret = qca_enable_regulator(vregs[i],
						   vreg_bulk[i].consumer);
			if (ret)
				break;
		}

		if (ret) {
			BT_ERR("failed to enable regulator:%s", vregs[i].name);
			/* turn off regulators which are enabled */
			for (i = i - 1; i >= 0; i--)
				qca_disable_regulator(vregs[i],
						      vreg_bulk[i].consumer);
		} else {
			qcadev->bt_power->vregs_on = true;
		}
	} else if (!on && qcadev->bt_power->vregs_on) {
		/* turn off regulator in reverse order */
		i = qcadev->bt_power->vreg_data->num_vregs - 1;
		for ( ; i >= 0; i--)
			qca_disable_regulator(vregs[i], vreg_bulk[i].consumer);

		qcadev->bt_power->vregs_on = false;
	}

	return ret;
}

static int qca_init_regulators(struct qca_power *qca,
				const struct qca_vreg *vregs, size_t num_vregs)
{
	int i;

	qca->vreg_bulk = devm_kcalloc(qca->dev, num_vregs,
				      sizeof(struct regulator_bulk_data),
				      GFP_KERNEL);
	if (!qca->vreg_bulk)
		return -ENOMEM;

	for (i = 0; i < num_vregs; i++)
		qca->vreg_bulk[i].supply = vregs[i].name;

	return devm_regulator_bulk_get(qca->dev, num_vregs, qca->vreg_bulk);
}

static int qca_serdev_probe(struct serdev_device *serdev)
{
	struct qca_serdev *qcadev;
	const struct qca_vreg_data *data;
	int err;

	qcadev = devm_kzalloc(&serdev->dev, sizeof(*qcadev), GFP_KERNEL);
	if (!qcadev)
		return -ENOMEM;

	qcadev->serdev_hu.serdev = serdev;
	data = of_device_get_match_data(&serdev->dev);
	serdev_device_set_drvdata(serdev, qcadev);
	if (data && data->soc_type == QCA_WCN3990) {
		qcadev->btsoc_type = QCA_WCN3990;
		qcadev->bt_power = devm_kzalloc(&serdev->dev,
						sizeof(struct qca_power),
						GFP_KERNEL);
		if (!qcadev->bt_power)
			return -ENOMEM;

		qcadev->bt_power->dev = &serdev->dev;
		qcadev->bt_power->vreg_data = data;
		err = qca_init_regulators(qcadev->bt_power, data->vregs,
					  data->num_vregs);
		if (err) {
			BT_ERR("Failed to init regulators:%d", err);
			goto out;
		}

		qcadev->bt_power->vregs_on = false;

		device_property_read_u32(&serdev->dev, "max-speed",
					 &qcadev->oper_speed);
		if (!qcadev->oper_speed)
			BT_DBG("UART will pick default operating speed");

		err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto);
		if (err) {
			BT_ERR("wcn3990 serdev registration failed");
			goto out;
		}
	} else {
		qcadev->btsoc_type = QCA_ROME;
		qcadev->bt_en = devm_gpiod_get(&serdev->dev, "enable",
					       GPIOD_OUT_LOW);
		if (IS_ERR(qcadev->bt_en)) {
			dev_err(&serdev->dev, "failed to acquire enable gpio\n");
			return PTR_ERR(qcadev->bt_en);
		}

		qcadev->susclk = devm_clk_get(&serdev->dev, NULL);
		if (IS_ERR(qcadev->susclk)) {
			dev_err(&serdev->dev, "failed to acquire clk\n");
			return PTR_ERR(qcadev->susclk);
		}

		err = clk_set_rate(qcadev->susclk, SUSCLK_RATE_32KHZ);
		if (err)
			return err;

		err = clk_prepare_enable(qcadev->susclk);
		if (err)
			return err;

		err = hci_uart_register_device(&qcadev->serdev_hu, &qca_proto);
		if (err)
			clk_disable_unprepare(qcadev->susclk);
	}

out:	return err;

}

static void qca_serdev_remove(struct serdev_device *serdev)
{
	struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);

	if (qcadev->btsoc_type == QCA_WCN3990)
		qca_power_shutdown(qcadev->serdev_hu.hdev);
	else
		clk_disable_unprepare(qcadev->susclk);

	hci_uart_unregister_device(&qcadev->serdev_hu);
}

static const struct of_device_id qca_bluetooth_of_match[] = {
	{ .compatible = "qcom,qca6174-bt" },
	{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data},
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);

static struct serdev_device_driver qca_serdev_driver = {
	.probe = qca_serdev_probe,
	.remove = qca_serdev_remove,
	.driver = {
		.name = "hci_uart_qca",
		.of_match_table = qca_bluetooth_of_match,
	},
};

int __init qca_init(void)
{
	serdev_device_driver_register(&qca_serdev_driver);

	return hci_uart_register_proto(&qca_proto);
}

int __exit qca_deinit(void)
{
	serdev_device_driver_unregister(&qca_serdev_driver);

	return hci_uart_unregister_proto(&qca_proto);
}
