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

	/* TX already aborted by received signal */
	if (pdphy->tx_status != -EINPROGRESS)
		return IRQ_HANDLED;

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

	if (pdphy->tx_status == -EINPROGRESS) {
		pdphy->tx_status = -EBUSY;
		wake_up(&pdphy->tx_waitq);
	}
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");
