/* Copyright (c) 2016-2017, Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only 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.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/irq.h>
#include <linux/of_irq.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include "usbpd.h"

#define USB_PDPHY_MAX_DATA_OBJ_LEN	28
#define USB_PDPHY_MSG_HDR_LEN		2

/* PD PHY register offsets and bit fields */
#define USB_PDPHY_MSG_CONFIG		0x40
#define MSG_CONFIG_PORT_DATA_ROLE	BIT(3)
#define MSG_CONFIG_PORT_POWER_ROLE	BIT(2)
#define MSG_CONFIG_SPEC_REV_MASK	(BIT(1) | BIT(0))

#define USB_PDPHY_EN_CONTROL		0x46
#define CONTROL_ENABLE			BIT(0)

#define USB_PDPHY_RX_STATUS		0x4A
#define RX_FRAME_TYPE			(BIT(0) | BIT(1) | BIT(2))

#define USB_PDPHY_FRAME_FILTER		0x4C
#define FRAME_FILTER_EN_HARD_RESET	BIT(5)
#define FRAME_FILTER_EN_SOP		BIT(0)

#define USB_PDPHY_TX_SIZE		0x42
#define TX_SIZE_MASK			0xF

#define USB_PDPHY_TX_CONTROL		0x44
#define TX_CONTROL_RETRY_COUNT		(BIT(6) | BIT(5))
#define TX_CONTROL_FRAME_TYPE		(BIT(4) | BIT(3) | BIT(2))
#define TX_CONTROL_FRAME_TYPE_CABLE_RESET (0x1 << 2)
#define TX_CONTROL_SEND_SIGNAL		BIT(1)
#define TX_CONTROL_SEND_MSG		BIT(0)

#define USB_PDPHY_RX_SIZE		0x48

#define USB_PDPHY_RX_ACKNOWLEDGE	0x4B
#define RX_BUFFER_TOKEN			BIT(0)

#define USB_PDPHY_BIST_MODE		0x4E
#define BIST_MODE_MASK			0xF
#define BIST_ENABLE			BIT(7)
#define PD_MSG_BIST			0x3
#define PD_BIST_TEST_DATA_MODE		0x8

#define USB_PDPHY_TX_BUFFER_HDR		0x60
#define USB_PDPHY_TX_BUFFER_DATA	0x62

#define USB_PDPHY_RX_BUFFER		0x80

#define USB_PDPHY_SEC_ACCESS		0xD0
#define USB_PDPHY_TRIM_3		0xF3

/* VDD regulator */
#define VDD_PDPHY_VOL_MIN		3088000 /* uV */
#define VDD_PDPHY_VOL_MAX		3088000 /* uV */
#define VDD_PDPHY_HPM_LOAD		3000 /* uA */

/* timers */
#define RECEIVER_RESPONSE_TIME		15	/* tReceiverResponse */
#define HARD_RESET_COMPLETE_TIME	5	/* tHardResetComplete */

struct usb_pdphy {
	struct device *dev;
	struct regmap *regmap;

	u16 base;
	struct regulator *vdd_pdphy;

	/* irqs */
	int sig_tx_irq;
	int sig_rx_irq;
	int msg_tx_irq;
	int msg_rx_irq;
	int msg_tx_failed_irq;
	int msg_tx_discarded_irq;
	int msg_rx_discarded_irq;

	void (*signal_cb)(struct usbpd *pd, enum pd_sig_type sig);
	void (*msg_rx_cb)(struct usbpd *pd, enum pd_sop_type sop,
			  u8 *buf, size_t len);
	void (*shutdown_cb)(struct usbpd *pd);

	/* write waitq */
	wait_queue_head_t tx_waitq;

	bool is_opened;
	int tx_status;
	u8 frame_filter_val;
	bool in_test_data_mode;

	enum data_role data_role;
	enum power_role power_role;

	struct usbpd *usbpd;

	/* debug */
	struct dentry *debug_root;
	unsigned int tx_bytes; /* hdr + data */
	unsigned int rx_bytes; /* hdr + data */
	unsigned int sig_tx_cnt;
	unsigned int sig_rx_cnt;
	unsigned int msg_tx_cnt;
	unsigned int msg_rx_cnt;
	unsigned int msg_tx_failed_cnt;
	unsigned int msg_tx_discarded_cnt;
	unsigned int msg_rx_discarded_cnt;
};

static struct usb_pdphy *__pdphy;

static int pdphy_dbg_status(struct seq_file *s, void *p)
{
	struct usb_pdphy *pdphy = s->private;

	seq_printf(s,
		"PD Phy driver status\n"
		"==================================================\n");
	seq_printf(s, "opened:         %10d\n", pdphy->is_opened);
	seq_printf(s, "tx status:      %10d\n", pdphy->tx_status);
	seq_printf(s, "tx bytes:       %10u\n", pdphy->tx_bytes);
	seq_printf(s, "rx bytes:       %10u\n", pdphy->rx_bytes);
	seq_printf(s, "data role:      %10u\n", pdphy->data_role);
	seq_printf(s, "power role:     %10u\n", pdphy->power_role);
	seq_printf(s, "frame filter:   %10u\n", pdphy->frame_filter_val);
	seq_printf(s, "sig tx cnt:     %10u\n", pdphy->sig_tx_cnt);
	seq_printf(s, "sig rx cnt:     %10u\n", pdphy->sig_rx_cnt);
	seq_printf(s, "msg tx cnt:     %10u\n", pdphy->msg_tx_cnt);
	seq_printf(s, "msg rx cnt:     %10u\n", pdphy->msg_rx_cnt);
	seq_printf(s, "msg tx failed cnt:    %10u\n",
			pdphy->msg_tx_failed_cnt);
	seq_printf(s, "msg tx discarded cnt: %10u\n",
			pdphy->msg_tx_discarded_cnt);
	seq_printf(s, "msg rx discarded cnt: %10u\n",
			pdphy->msg_rx_discarded_cnt);

	return 0;
}

static int pdphy_dbg_status_open(struct inode *inode, struct file *file)
{
	return single_open(file, pdphy_dbg_status, inode->i_private);
}

static const struct file_operations status_ops = {
	.owner		= THIS_MODULE,
	.open		= pdphy_dbg_status_open,
	.llseek		= seq_lseek,
	.read		= seq_read,
	.release	= single_release,
};

static void pdphy_create_debugfs_entries(struct usb_pdphy *pdphy)
{
	struct dentry *ent;

	pdphy->debug_root = debugfs_create_dir("usb-pdphy", NULL);
	if (!pdphy->debug_root) {
		dev_warn(pdphy->dev, "Couldn't create debug dir\n");
		return;
	}

	ent = debugfs_create_file("status", 0400, pdphy->debug_root, pdphy,
				  &status_ops);
	if (!ent) {
		dev_warn(pdphy->dev, "Couldn't create status file\n");
		debugfs_remove(pdphy->debug_root);
	}
}

static int pdphy_enable_power(struct usb_pdphy *pdphy, bool on)
{
	int ret = 0;

	dev_dbg(pdphy->dev, "%s turn %s regulator.\n", __func__,
		on ? "on" : "off");

	if (!on)
		goto disable_pdphy_vdd;

	ret = regulator_set_load(pdphy->vdd_pdphy, VDD_PDPHY_HPM_LOAD);
	if (ret < 0) {
		dev_err(pdphy->dev, "Unable to set HPM of vdd_pdphy:%d\n", ret);
		return ret;
	}

	ret = regulator_set_voltage(pdphy->vdd_pdphy, VDD_PDPHY_VOL_MIN,
						VDD_PDPHY_VOL_MAX);
	if (ret) {
		dev_err(pdphy->dev,
				"set voltage failed for vdd_pdphy:%d\n", ret);
		goto put_pdphy_vdd_lpm;
	}

	ret = regulator_enable(pdphy->vdd_pdphy);
	if (ret) {
		dev_err(pdphy->dev, "Unable to enable vdd_pdphy:%d\n", ret);
		goto unset_pdphy_vdd;
	}

	dev_dbg(pdphy->dev, "%s: PD PHY regulator turned ON.\n", __func__);
	return ret;

disable_pdphy_vdd:
	ret = regulator_disable(pdphy->vdd_pdphy);
	if (ret)
		dev_err(pdphy->dev, "Unable to disable vdd_pdphy:%d\n", ret);

unset_pdphy_vdd:
	ret = regulator_set_voltage(pdphy->vdd_pdphy, 0, VDD_PDPHY_VOL_MAX);
	if (ret)
		dev_err(pdphy->dev,
			"Unable to set (0) voltage for vdd_pdphy:%d\n", ret);

put_pdphy_vdd_lpm:
	ret = regulator_set_load(pdphy->vdd_pdphy, 0);
	if (ret < 0)
		dev_err(pdphy->dev, "Unable to set (0) HPM of vdd_pdphy\n");

	return ret;
}

void pdphy_enable_irq(struct usb_pdphy *pdphy, bool enable)
{
	if (enable) {
		enable_irq(pdphy->sig_tx_irq);
		enable_irq(pdphy->sig_rx_irq);
		enable_irq_wake(pdphy->sig_rx_irq);
		enable_irq(pdphy->msg_tx_irq);
		if (!pdphy->in_test_data_mode) {
			enable_irq(pdphy->msg_rx_irq);
			enable_irq_wake(pdphy->msg_rx_irq);
		}
		enable_irq(pdphy->msg_tx_failed_irq);
		enable_irq(pdphy->msg_tx_discarded_irq);
		enable_irq(pdphy->msg_rx_discarded_irq);
		return;
	}

	disable_irq(pdphy->sig_tx_irq);
	disable_irq(pdphy->sig_rx_irq);
	disable_irq_wake(pdphy->sig_rx_irq);
	disable_irq(pdphy->msg_tx_irq);
	if (!pdphy->in_test_data_mode) {
		disable_irq(pdphy->msg_rx_irq);
		disable_irq_wake(pdphy->msg_rx_irq);
	}
	disable_irq(pdphy->msg_tx_failed_irq);
	disable_irq(pdphy->msg_tx_discarded_irq);
	disable_irq(pdphy->msg_rx_discarded_irq);
}

static int pdphy_reg_read(struct usb_pdphy *pdphy, u8 *val, u16 addr, int count)
{
	int ret;

	ret = regmap_bulk_read(pdphy->regmap, pdphy->base + addr, val, count);
	if (ret) {
		dev_err(pdphy->dev, "read failed: addr=0x%04x, ret=%d\n",
			pdphy->base + addr, ret);
		return ret;
	}

	return 0;
}

/* Write multiple registers to device with block of data */
static int pdphy_bulk_reg_write(struct usb_pdphy *pdphy, u16 addr,
	const void *val, u8 val_cnt)
{
	int ret;

	ret = regmap_bulk_write(pdphy->regmap, pdphy->base + addr,
			val, val_cnt);
	if (ret) {
		dev_err(pdphy->dev, "bulk write failed: addr=0x%04x, ret=%d\n",
				pdphy->base + addr, ret);
		return ret;
	}

	return 0;
}

/* Writes a single byte to the specified register */
static inline int pdphy_reg_write(struct usb_pdphy *pdphy, u16 addr, u8 val)
{
	return pdphy_bulk_reg_write(pdphy, addr, &val, 1);
}

/* Writes to the specified register limited by the bit mask */
static int pdphy_masked_write(struct usb_pdphy *pdphy, u16 addr,
	u8 mask, u8 val)
{
	int ret;

	ret = regmap_update_bits(pdphy->regmap, pdphy->base + addr, mask, val);
	if (ret) {
		dev_err(pdphy->dev, "write failed: addr=0x%04x, ret=%d\n",
				pdphy->base + addr, ret);
		return ret;
	}

	return 0;
}

int pd_phy_update_roles(enum data_role dr, enum power_role pr)
{
	struct usb_pdphy *pdphy = __pdphy;

	return pdphy_masked_write(pdphy, USB_PDPHY_MSG_CONFIG,
		(MSG_CONFIG_PORT_DATA_ROLE | MSG_CONFIG_PORT_POWER_ROLE),
		((dr == DR_DFP ? MSG_CONFIG_PORT_DATA_ROLE : 0) |
		 (pr == PR_SRC ? MSG_CONFIG_PORT_POWER_ROLE : 0)));
}
EXPORT_SYMBOL(pd_phy_update_roles);

int pd_phy_open(struct pd_phy_params *params)
{
	int ret;
	struct usb_pdphy *pdphy = __pdphy;

	if (!pdphy) {
		pr_err("%s: pdphy not found\n", __func__);
		return -ENODEV;
	}

	if (pdphy->is_opened) {
		dev_err(pdphy->dev, "%s: already opened\n", __func__);
		return -EBUSY;
	}

	pdphy->signal_cb = params->signal_cb;
	pdphy->msg_rx_cb = params->msg_rx_cb;
	pdphy->shutdown_cb = params->shutdown_cb;
	pdphy->data_role = params->data_role;
	pdphy->power_role = params->power_role;
	pdphy->frame_filter_val = params->frame_filter_val;

	dev_dbg(pdphy->dev, "%s: DR %x PR %x frame filter val %x\n", __func__,
		pdphy->data_role, pdphy->power_role, pdphy->frame_filter_val);

	ret = pdphy_enable_power(pdphy, true);
	if (ret)
		return ret;

	/* update data and power role to be used in GoodCRC generation */
	ret = pd_phy_update_roles(pdphy->data_role, pdphy->power_role);
	if (ret)
		return ret;

	/* PD 2.0  phy */
	ret = pdphy_masked_write(pdphy, USB_PDPHY_MSG_CONFIG,
			MSG_CONFIG_SPEC_REV_MASK, USBPD_REV_20);
	if (ret)
		return ret;

	ret = pdphy_reg_write(pdphy, USB_PDPHY_EN_CONTROL, 0);
	if (ret)
		return ret;

	ret = pdphy_reg_write(pdphy, USB_PDPHY_EN_CONTROL, CONTROL_ENABLE);
	if (ret)
		return ret;

	/* update frame filter */
	ret = pdphy_reg_write(pdphy, USB_PDPHY_FRAME_FILTER,
			pdphy->frame_filter_val);
	if (ret)
		return ret;

	/* initialize Rx buffer ownership to PDPHY HW */
	ret = pdphy_reg_write(pdphy, USB_PDPHY_RX_ACKNOWLEDGE, 0);
	if (ret)
		return ret;

	pdphy->is_opened = true;
	pdphy_enable_irq(pdphy, true);

	return ret;
}
EXPORT_SYMBOL(pd_phy_open);

int pd_phy_signal(enum pd_sig_type sig)
{
	u8 val;
	int ret;
	struct usb_pdphy *pdphy = __pdphy;

	dev_dbg(pdphy->dev, "%s: type %d\n", __func__, sig);

	if (!pdphy) {
		pr_err("%s: pdphy not found\n", __func__);
		return -ENODEV;
	}

	if (!pdphy->is_opened) {
		dev_dbg(pdphy->dev, "%s: pdphy disabled\n", __func__);
		return -ENODEV;
	}

	pdphy->tx_status = -EINPROGRESS;

	ret = pdphy_reg_write(pdphy, USB_PDPHY_TX_CONTROL, 0);
	if (ret)
		return ret;

	usleep_range(2, 3);

	val = (sig == CABLE_RESET_SIG ? TX_CONTROL_FRAME_TYPE_CABLE_RESET : 0)
		| TX_CONTROL_SEND_SIGNAL;

	ret = pdphy_reg_write(pdphy, USB_PDPHY_TX_CONTROL, val);
	if (ret)
		return ret;

	ret = wait_event_interruptible_timeout(pdphy->tx_waitq,
		pdphy->tx_status != -EINPROGRESS,
		msecs_to_jiffies(HARD_RESET_COMPLETE_TIME));
	if (ret <= 0) {
		dev_err(pdphy->dev, "%s: failed ret %d", __func__, ret);
		return ret ? ret : -ETIMEDOUT;
	}

	ret = pdphy_reg_write(pdphy, USB_PDPHY_TX_CONTROL, 0);

	if (pdphy->tx_status)
		return pdphy->tx_status;

	if (sig == HARD_RESET_SIG)
		/* Frame filter is reconfigured in pd_phy_open() */
		return pdphy_reg_write(pdphy, USB_PDPHY_FRAME_FILTER, 0);

	return 0;
}
EXPORT_SYMBOL(pd_phy_signal);

int pd_phy_write(u16 hdr, const u8 *data, size_t data_len, enum pd_sop_type sop)
{
	u8 val;
	int ret;
	size_t total_len = data_len + USB_PDPHY_MSG_HDR_LEN;
	struct usb_pdphy *pdphy = __pdphy;

	dev_dbg(pdphy->dev, "%s: hdr %x frame sop_type %d\n",
			__func__, hdr, sop);

	if (data && data_len)
		print_hex_dump_debug("tx data obj:", DUMP_PREFIX_NONE, 32, 4,
				data, data_len, false);

	if (!pdphy) {
		pr_err("%s: pdphy not found\n", __func__);
		return -ENODEV;
	}

	if (!pdphy->is_opened) {
		dev_dbg(pdphy->dev, "%s: pdphy disabled\n", __func__);
		return -ENODEV;
	}

	if (data_len > USB_PDPHY_MAX_DATA_OBJ_LEN) {
		dev_err(pdphy->dev, "%s: invalid data object len %zu\n",
			__func__, data_len);
		return -EINVAL;
	}

	ret = pdphy_reg_read(pdphy, &val, USB_PDPHY_RX_ACKNOWLEDGE, 1);
	if (ret || val) {
		dev_err(pdphy->dev, "%s: RX message pending\n", __func__);
		return -EBUSY;
	}

	pdphy->tx_status = -EINPROGRESS;

	/* write 2 byte SOP message header */
	ret = pdphy_bulk_reg_write(pdphy, USB_PDPHY_TX_BUFFER_HDR, (u8 *)&hdr,
			USB_PDPHY_MSG_HDR_LEN);
	if (ret)
		return ret;

	if (data && data_len) {
		/* write data objects of SOP message */
		ret = pdphy_bulk_reg_write(pdphy, USB_PDPHY_TX_BUFFER_DATA,
				data, data_len);
		if (ret)
			return ret;
	}

	ret = pdphy_reg_write(pdphy, USB_PDPHY_TX_SIZE, total_len - 1);
	if (ret)
		return ret;

	ret = pdphy_reg_write(pdphy, USB_PDPHY_TX_CONTROL, 0);
	if (ret)
		return ret;

	usleep_range(2, 3);

	val = TX_CONTROL_RETRY_COUNT | (sop << 2) | TX_CONTROL_SEND_MSG;

	ret = pdphy_reg_write(pdphy, USB_PDPHY_TX_CONTROL, val);
	if (ret)
		return ret;

	ret = wait_event_interruptible_timeout(pdphy->tx_waitq,
		pdphy->tx_status != -EINPROGRESS,
		msecs_to_jiffies(RECEIVER_RESPONSE_TIME));
	if (ret <= 0) {
		dev_err(pdphy->dev, "%s: failed ret %d", __func__, ret);
		return ret ? ret : -ETIMEDOUT;
	}

	if (hdr && !pdphy->tx_status)
		pdphy->tx_bytes += data_len + USB_PDPHY_MSG_HDR_LEN;

	return pdphy->tx_status ? pdphy->tx_status : 0;
}
EXPORT_SYMBOL(pd_phy_write);

void pd_phy_close(void)
{
	int ret;
	struct usb_pdphy *pdphy = __pdphy;

	if (!pdphy) {
		pr_err("%s: pdphy not found\n", __func__);
		return;
	}

	if (!pdphy->is_opened) {
		dev_err(pdphy->dev, "%s: not opened\n", __func__);
		return;
	}

	pdphy->is_opened = false;
	pdphy_enable_irq(pdphy, false);

	pdphy->tx_status = -ESHUTDOWN;

	wake_up_all(&pdphy->tx_waitq);

	pdphy_reg_write(pdphy, USB_PDPHY_BIST_MODE, 0);
	pdphy->in_test_data_mode = false;

	ret = pdphy_reg_write(pdphy, USB_PDPHY_TX_CONTROL, 0);
	if (ret)
		return;

	ret = pdphy_reg_write(pdphy, USB_PDPHY_EN_CONTROL, 0);
	if (ret)
		return;

	pdphy_enable_power(pdphy, false);
}
EXPORT_SYMBOL(pd_phy_close);

static irqreturn_t pdphy_msg_tx_irq(int irq, void *data)
{
	struct usb_pdphy *pdphy = data;

	if (irq == pdphy->msg_tx_irq) {
		pdphy->msg_tx_cnt++;
		pdphy->tx_status = 0;
	} else if (irq == pdphy->msg_tx_discarded_irq) {
		pdphy->msg_tx_discarded_cnt++;
		pdphy->tx_status = -EBUSY;
	} else if (irq == pdphy->msg_tx_failed_irq) {
		pdphy->msg_tx_failed_cnt++;
		pdphy->tx_status = -EFAULT;
	} else {
		dev_err(pdphy->dev, "spurious irq #%d received\n", irq);
		return IRQ_NONE;
	}

	wake_up(&pdphy->tx_waitq);

	return IRQ_HANDLED;
}

static irqreturn_t pdphy_msg_rx_discarded_irq(int irq, void *data)
{
	struct usb_pdphy *pdphy = data;

	pdphy->msg_rx_discarded_cnt++;

	return IRQ_HANDLED;
}

static irqreturn_t pdphy_sig_rx_irq_thread(int irq, void *data)
{
	u8 rx_status, frame_type;
	int ret;
	struct usb_pdphy *pdphy = data;

	pdphy->sig_rx_cnt++;

	ret = pdphy_reg_read(pdphy, &rx_status, USB_PDPHY_RX_STATUS, 1);
	if (ret)
		goto done;

	frame_type = rx_status & RX_FRAME_TYPE;
	if (frame_type != HARD_RESET_SIG) {
		dev_err(pdphy->dev, "%s:unsupported frame type %d\n",
			__func__, frame_type);
		goto done;
	}

	/* Frame filter is reconfigured in pd_phy_open() */
	ret = pdphy_reg_write(pdphy, USB_PDPHY_FRAME_FILTER, 0);

	if (pdphy->signal_cb)
		pdphy->signal_cb(pdphy->usbpd, frame_type);

done:
	return IRQ_HANDLED;
}

static irqreturn_t pdphy_sig_tx_irq_thread(int irq, void *data)
{
	struct usb_pdphy *pdphy = data;

	/* in case of exit from BIST Carrier Mode 2, clear BIST_MODE */
	pdphy_reg_write(pdphy, USB_PDPHY_BIST_MODE, 0);

	pdphy->sig_tx_cnt++;
	pdphy->tx_status = 0;
	wake_up(&pdphy->tx_waitq);

	return IRQ_HANDLED;
}

static int pd_phy_bist_mode(u8 bist_mode)
{
	struct usb_pdphy *pdphy = __pdphy;

	dev_dbg(pdphy->dev, "%s: enter BIST mode %d\n", __func__, bist_mode);

	pdphy_reg_write(pdphy, USB_PDPHY_BIST_MODE, 0);

	udelay(5);

	return pdphy_masked_write(pdphy, USB_PDPHY_BIST_MODE,
			BIST_MODE_MASK | BIST_ENABLE, bist_mode | BIST_ENABLE);
}

static irqreturn_t pdphy_msg_rx_irq_thread(int irq, void *data)
{
	u8 size, rx_status, frame_type;
	u8 buf[32];
	int ret;
	struct usb_pdphy *pdphy = data;

	pdphy->msg_rx_cnt++;

	ret = pdphy_reg_read(pdphy, &size, USB_PDPHY_RX_SIZE, 1);
	if (ret)
		goto done;

	if (!size || size > 31) {
		dev_err(pdphy->dev, "%s: invalid size %d\n", __func__, size);
		goto done;
	}

	ret = pdphy_reg_read(pdphy, &rx_status, USB_PDPHY_RX_STATUS, 1);
	if (ret)
		goto done;

	frame_type = rx_status & RX_FRAME_TYPE;
	if (frame_type != SOP_MSG) {
		dev_err(pdphy->dev, "%s:unsupported frame type %d\n",
			__func__, frame_type);
		goto done;
	}

	ret = pdphy_reg_read(pdphy, buf, USB_PDPHY_RX_BUFFER, size + 1);
	if (ret)
		goto done;

	/* ack to change ownership of rx buffer back to PDPHY RX HW */
	pdphy_reg_write(pdphy, USB_PDPHY_RX_ACKNOWLEDGE, 0);

	if (((buf[0] & 0xf) == PD_MSG_BIST) && size >= 5) { /* BIST */
		u8 mode = buf[5] >> 4; /* [31:28] of 1st data object */

		pd_phy_bist_mode(mode);
		pdphy_reg_write(pdphy, USB_PDPHY_RX_ACKNOWLEDGE, 0);

		if (mode == PD_BIST_TEST_DATA_MODE) {
			pdphy->in_test_data_mode = true;
			disable_irq_nosync(irq);
		}
		goto done;
	}

	if (pdphy->msg_rx_cb)
		pdphy->msg_rx_cb(pdphy->usbpd, frame_type, buf, size + 1);

	print_hex_dump_debug("rx msg:", DUMP_PREFIX_NONE, 32, 4, buf, size + 1,
		false);
	pdphy->rx_bytes += size + 1;
done:
	return IRQ_HANDLED;
}

static int pdphy_request_irq(struct usb_pdphy *pdphy,
				struct device_node *node,
				int *irq_num, const char *irq_name,
				irqreturn_t (irq_handler)(int irq, void *data),
				irqreturn_t (thread_fn)(int irq, void *data),
				int flags)
{
	int ret;

	*irq_num = of_irq_get_byname(node, irq_name);
	if (*irq_num < 0) {
		dev_err(pdphy->dev, "Unable to get %s irqn", irq_name);
		ret = -ENXIO;
	}

	irq_set_status_flags(*irq_num, IRQ_NOAUTOEN);
	ret = devm_request_threaded_irq(pdphy->dev, *irq_num, irq_handler,
			thread_fn, flags, irq_name, pdphy);
	if (ret < 0) {
		dev_err(pdphy->dev, "Unable to request %s irq: %dn",
				irq_name, ret);
		ret = -ENXIO;
	}

	return 0;
}

static int pdphy_probe(struct platform_device *pdev)
{
	int ret;
	unsigned int base;
	struct usb_pdphy *pdphy;

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

	pdphy->regmap = dev_get_regmap(pdev->dev.parent, NULL);
	if (!pdphy->regmap) {
		dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
		return -EINVAL;
	}

	dev_set_drvdata(&pdev->dev, pdphy);

	ret = of_property_read_u32(pdev->dev.of_node, "reg", &base);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to get reg base address ret = %d\n",
			ret);
		return ret;
	}

	pdphy->base = base;
	pdphy->dev = &pdev->dev;

	init_waitqueue_head(&pdphy->tx_waitq);

	pdphy->vdd_pdphy = devm_regulator_get(&pdev->dev, "vdd-pdphy");
	if (IS_ERR(pdphy->vdd_pdphy)) {
		dev_err(&pdev->dev, "unable to get vdd-pdphy\n");
		return PTR_ERR(pdphy->vdd_pdphy);
	}

	ret = pdphy_request_irq(pdphy, pdev->dev.of_node,
		&pdphy->sig_tx_irq, "sig-tx", NULL,
		pdphy_sig_tx_irq_thread, (IRQF_TRIGGER_RISING | IRQF_ONESHOT));
	if (ret < 0)
		return ret;

	ret = pdphy_request_irq(pdphy, pdev->dev.of_node,
		&pdphy->sig_rx_irq, "sig-rx", NULL,
		pdphy_sig_rx_irq_thread, (IRQF_TRIGGER_RISING | IRQF_ONESHOT));
	if (ret < 0)
		return ret;

	ret = pdphy_request_irq(pdphy, pdev->dev.of_node,
		&pdphy->msg_tx_irq, "msg-tx", pdphy_msg_tx_irq,
		NULL, (IRQF_TRIGGER_RISING | IRQF_ONESHOT));
	if (ret < 0)
		return ret;

	ret = pdphy_request_irq(pdphy, pdev->dev.of_node,
		&pdphy->msg_rx_irq, "msg-rx", NULL,
		pdphy_msg_rx_irq_thread, (IRQF_TRIGGER_RISING | IRQF_ONESHOT));
	if (ret < 0)
		return ret;

	ret = pdphy_request_irq(pdphy, pdev->dev.of_node,
		&pdphy->msg_tx_failed_irq, "msg-tx-failed", pdphy_msg_tx_irq,
		NULL, (IRQF_TRIGGER_RISING | IRQF_ONESHOT));
	if (ret < 0)
		return ret;

	ret = pdphy_request_irq(pdphy, pdev->dev.of_node,
		&pdphy->msg_tx_discarded_irq, "msg-tx-discarded",
		pdphy_msg_tx_irq, NULL,
		(IRQF_TRIGGER_RISING | IRQF_ONESHOT));
	if (ret < 0)
		return ret;

	ret = pdphy_request_irq(pdphy, pdev->dev.of_node,
		&pdphy->msg_rx_discarded_irq, "msg-rx-discarded",
		pdphy_msg_rx_discarded_irq, NULL,
		(IRQF_TRIGGER_RISING | IRQF_ONESHOT));
	if (ret < 0)
		return ret;

	ret = pdphy_reg_write(pdphy, USB_PDPHY_SEC_ACCESS, 0xA5);
	if (ret)
		return ret;

	ret = pdphy_reg_write(pdphy, USB_PDPHY_TRIM_3, 0x2);
	if (ret)
		return ret;

	/* usbpd_create() could call back to us, so have __pdphy ready */
	__pdphy = pdphy;

	pdphy->usbpd = usbpd_create(&pdev->dev);
	if (IS_ERR(pdphy->usbpd)) {
		dev_err(&pdev->dev, "usbpd_create failed: %ld\n",
				PTR_ERR(pdphy->usbpd));
		__pdphy = NULL;
		return PTR_ERR(pdphy->usbpd);
	}

	pdphy_create_debugfs_entries(pdphy);

	return 0;
}

static int pdphy_remove(struct platform_device *pdev)
{
	struct usb_pdphy *pdphy = platform_get_drvdata(pdev);

	debugfs_remove_recursive(pdphy->debug_root);
	usbpd_destroy(pdphy->usbpd);

	if (pdphy->is_opened)
		pd_phy_close();

	__pdphy = NULL;

	return 0;
}

static void pdphy_shutdown(struct platform_device *pdev)
{
	struct usb_pdphy *pdphy = platform_get_drvdata(pdev);

	/* let protocol engine shutdown the pdphy synchronously */
	if (pdphy->shutdown_cb)
		pdphy->shutdown_cb(pdphy->usbpd);
}

static const struct of_device_id pdphy_match_table[] = {
	{
		.compatible	 = "qcom,qpnp-pdphy",
	},
	{ },
};
MODULE_DEVICE_TABLE(of, pdphy_match_table);

static struct platform_driver pdphy_driver = {
	 .driver	 = {
		 .name			= "qpnp-pdphy",
		 .of_match_table	= pdphy_match_table,
	 },
	 .probe		= pdphy_probe,
	 .remove	= pdphy_remove,
	 .shutdown	= pdphy_shutdown,
};

module_platform_driver(pdphy_driver);

MODULE_DESCRIPTION("QPNP PD PHY Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:qpnp-pdphy");
