// SPDX-License-Identifier: GPL-2.0
/*
 * UCSI driver for Cypress CCGx Type-C controller
 *
 * Copyright (C) 2017-2018 NVIDIA Corporation. All rights reserved.
 * Author: Ajay Gupta <ajayg@nvidia.com>
 *
 * Some code borrowed from drivers/usb/typec/ucsi/ucsi_acpi.c
 */
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/usb/typec_dp.h>

#include <asm/unaligned.h>
#include "ucsi.h"

enum enum_fw_mode {
	BOOT,   /* bootloader */
	FW1,    /* FW partition-1 (contains secondary fw) */
	FW2,    /* FW partition-2 (contains primary fw) */
	FW_INVALID,
};

#define CCGX_RAB_DEVICE_MODE			0x0000
#define CCGX_RAB_INTR_REG			0x0006
#define  DEV_INT				BIT(0)
#define  PORT0_INT				BIT(1)
#define  PORT1_INT				BIT(2)
#define  UCSI_READ_INT				BIT(7)
#define CCGX_RAB_JUMP_TO_BOOT			0x0007
#define  TO_BOOT				'J'
#define  TO_ALT_FW				'A'
#define CCGX_RAB_RESET_REQ			0x0008
#define  RESET_SIG				'R'
#define  CMD_RESET_I2C				0x0
#define  CMD_RESET_DEV				0x1
#define CCGX_RAB_ENTER_FLASHING			0x000A
#define  FLASH_ENTER_SIG			'P'
#define CCGX_RAB_VALIDATE_FW			0x000B
#define CCGX_RAB_FLASH_ROW_RW			0x000C
#define  FLASH_SIG				'F'
#define  FLASH_RD_CMD				0x0
#define  FLASH_WR_CMD				0x1
#define  FLASH_FWCT1_WR_CMD			0x2
#define  FLASH_FWCT2_WR_CMD			0x3
#define  FLASH_FWCT_SIG_WR_CMD			0x4
#define CCGX_RAB_READ_ALL_VER			0x0010
#define CCGX_RAB_READ_FW2_VER			0x0020
#define CCGX_RAB_UCSI_CONTROL			0x0039
#define CCGX_RAB_UCSI_CONTROL_START		BIT(0)
#define CCGX_RAB_UCSI_CONTROL_STOP		BIT(1)
#define CCGX_RAB_UCSI_DATA_BLOCK(offset)	(0xf000 | ((offset) & 0xff))
#define REG_FLASH_RW_MEM        0x0200
#define DEV_REG_IDX				CCGX_RAB_DEVICE_MODE
#define CCGX_RAB_PDPORT_ENABLE			0x002C
#define  PDPORT_1		BIT(0)
#define  PDPORT_2		BIT(1)
#define CCGX_RAB_RESPONSE			0x007E
#define  ASYNC_EVENT				BIT(7)

/* CCGx events & async msg codes */
#define RESET_COMPLETE		0x80
#define EVENT_INDEX		RESET_COMPLETE
#define PORT_CONNECT_DET	0x84
#define PORT_DISCONNECT_DET	0x85
#define ROLE_SWAP_COMPELETE	0x87

/* ccg firmware */
#define CYACD_LINE_SIZE         527
#define CCG4_ROW_SIZE           256
#define FW1_METADATA_ROW        0x1FF
#define FW2_METADATA_ROW        0x1FE
#define FW_CFG_TABLE_SIG_SIZE	256

static int secondary_fw_min_ver = 41;

enum enum_flash_mode {
	SECONDARY_BL,	/* update secondary using bootloader */
	PRIMARY,	/* update primary using secondary */
	SECONDARY,	/* update secondary using primary */
	FLASH_NOT_NEEDED,	/* update not required */
	FLASH_INVALID,
};

static const char * const ccg_fw_names[] = {
	"ccg_boot.cyacd",
	"ccg_primary.cyacd",
	"ccg_secondary.cyacd"
};

struct ccg_dev_info {
#define CCG_DEVINFO_FWMODE_SHIFT (0)
#define CCG_DEVINFO_FWMODE_MASK (0x3 << CCG_DEVINFO_FWMODE_SHIFT)
#define CCG_DEVINFO_PDPORTS_SHIFT (2)
#define CCG_DEVINFO_PDPORTS_MASK (0x3 << CCG_DEVINFO_PDPORTS_SHIFT)
	u8 mode;
	u8 bl_mode;
	__le16 silicon_id;
	__le16 bl_last_row;
} __packed;

struct version_format {
	__le16 build;
	u8 patch;
	u8 ver;
#define CCG_VERSION_PATCH(x) ((x) << 16)
#define CCG_VERSION(x)	((x) << 24)
#define CCG_VERSION_MIN_SHIFT (0)
#define CCG_VERSION_MIN_MASK (0xf << CCG_VERSION_MIN_SHIFT)
#define CCG_VERSION_MAJ_SHIFT (4)
#define CCG_VERSION_MAJ_MASK (0xf << CCG_VERSION_MAJ_SHIFT)
} __packed;

/*
 * Firmware version 3.1.10 or earlier, built for NVIDIA has known issue
 * of missing interrupt when a device is connected for runtime resume
 */
#define CCG_FW_BUILD_NVIDIA	(('n' << 8) | 'v')
#define CCG_OLD_FW_VERSION	(CCG_VERSION(0x31) | CCG_VERSION_PATCH(10))

/* Firmware for Tegra doesn't support UCSI ALT command, built
 * for NVIDIA has known issue of reporting wrong capability info
 */
#define CCG_FW_BUILD_NVIDIA_TEGRA	(('g' << 8) | 'n')

/* Altmode offset for NVIDIA Function Test Board (FTB) */
#define NVIDIA_FTB_DP_OFFSET	(2)
#define NVIDIA_FTB_DBG_OFFSET	(3)

struct version_info {
	struct version_format base;
	struct version_format app;
};

struct fw_config_table {
	u32 identity;
	u16 table_size;
	u8 fwct_version;
	u8 is_key_change;
	u8 guid[16];
	struct version_format base;
	struct version_format app;
	u8 primary_fw_digest[32];
	u32 key_exp_length;
	u8 key_modulus[256];
	u8 key_exp[4];
};

/* CCGx response codes */
enum ccg_resp_code {
	CMD_NO_RESP             = 0x00,
	CMD_SUCCESS             = 0x02,
	FLASH_DATA_AVAILABLE    = 0x03,
	CMD_INVALID             = 0x05,
	FLASH_UPDATE_FAIL       = 0x07,
	INVALID_FW              = 0x08,
	INVALID_ARG             = 0x09,
	CMD_NOT_SUPPORT         = 0x0A,
	TRANSACTION_FAIL        = 0x0C,
	PD_CMD_FAIL             = 0x0D,
	UNDEF_ERROR             = 0x0F,
	INVALID_RESP		= 0x10,
};

#define CCG_EVENT_MAX	(EVENT_INDEX + 43)

struct ccg_cmd {
	u16 reg;
	u32 data;
	int len;
	u32 delay; /* ms delay for cmd timeout  */
};

struct ccg_resp {
	u8 code;
	u8 length;
};

struct ucsi_ccg_altmode {
	u16 svid;
	u32 mid;
	u8 linked_idx;
	u8 active_idx;
#define UCSI_MULTI_DP_INDEX	(0xff)
	bool checked;
} __packed;

#define CCGX_MESSAGE_IN_MAX 4
struct op_region {
	__le32 cci;
	__le32 message_in[CCGX_MESSAGE_IN_MAX];
};

struct ucsi_ccg {
	struct device *dev;
	struct ucsi *ucsi;
	struct i2c_client *client;

	struct ccg_dev_info info;
	/* version info for boot, primary and secondary */
	struct version_info version[FW2 + 1];
	u32 fw_version;
	/* CCG HPI communication flags */
	unsigned long flags;
#define RESET_PENDING	0
#define DEV_CMD_PENDING	1
	struct ccg_resp dev_resp;
	u8 cmd_resp;
	int port_num;
	int irq;
	struct work_struct work;
	struct mutex lock; /* to sync between user and driver thread */

	/* fw build with vendor information */
	u16 fw_build;
	struct work_struct pm_work;

	struct completion complete;

	u64 last_cmd_sent;
	bool has_multiple_dp;
	struct ucsi_ccg_altmode orig[UCSI_MAX_ALTMODES];
	struct ucsi_ccg_altmode updated[UCSI_MAX_ALTMODES];

	/*
	 * This spinlock protects op_data which includes CCI and MESSAGE_IN that
	 * will be updated in ISR
	 */
	spinlock_t op_lock;
	struct op_region op_data;
};

static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len)
{
	struct i2c_client *client = uc->client;
	const struct i2c_adapter_quirks *quirks = client->adapter->quirks;
	unsigned char buf[2];
	struct i2c_msg msgs[] = {
		{
			.addr	= client->addr,
			.flags  = 0x0,
			.len	= sizeof(buf),
			.buf	= buf,
		},
		{
			.addr	= client->addr,
			.flags  = I2C_M_RD,
			.buf	= data,
		},
	};
	u32 rlen, rem_len = len, max_read_len = len;
	int status;

	/* check any max_read_len limitation on i2c adapter */
	if (quirks && quirks->max_read_len)
		max_read_len = quirks->max_read_len;

	pm_runtime_get_sync(uc->dev);
	while (rem_len > 0) {
		msgs[1].buf = &data[len - rem_len];
		rlen = min_t(u16, rem_len, max_read_len);
		msgs[1].len = rlen;
		put_unaligned_le16(rab, buf);
		status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
		if (status < 0) {
			dev_err(uc->dev, "i2c_transfer failed %d\n", status);
			pm_runtime_put_sync(uc->dev);
			return status;
		}
		rab += rlen;
		rem_len -= rlen;
	}

	pm_runtime_put_sync(uc->dev);
	return 0;
}

static int ccg_write(struct ucsi_ccg *uc, u16 rab, const u8 *data, u32 len)
{
	struct i2c_client *client = uc->client;
	unsigned char *buf;
	struct i2c_msg msgs[] = {
		{
			.addr	= client->addr,
			.flags  = 0x0,
		}
	};
	int status;

	buf = kzalloc(len + sizeof(rab), GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	put_unaligned_le16(rab, buf);
	memcpy(buf + sizeof(rab), data, len);

	msgs[0].len = len + sizeof(rab);
	msgs[0].buf = buf;

	pm_runtime_get_sync(uc->dev);
	status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
	if (status < 0) {
		dev_err(uc->dev, "i2c_transfer failed %d\n", status);
		pm_runtime_put_sync(uc->dev);
		kfree(buf);
		return status;
	}

	pm_runtime_put_sync(uc->dev);
	kfree(buf);
	return 0;
}

static int ccg_op_region_update(struct ucsi_ccg *uc, u32 cci)
{
	u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(UCSI_MESSAGE_IN);
	struct op_region *data = &uc->op_data;
	unsigned char *buf;
	size_t size = sizeof(data->message_in);

	buf = kzalloc(size, GFP_ATOMIC);
	if (!buf)
		return -ENOMEM;
	if (UCSI_CCI_LENGTH(cci)) {
		int ret = ccg_read(uc, reg, (void *)buf, size);

		if (ret) {
			kfree(buf);
			return ret;
		}
	}

	spin_lock(&uc->op_lock);
	data->cci = cpu_to_le32(cci);
	if (UCSI_CCI_LENGTH(cci))
		memcpy(&data->message_in, buf, size);
	spin_unlock(&uc->op_lock);
	kfree(buf);
	return 0;
}

static int ucsi_ccg_init(struct ucsi_ccg *uc)
{
	unsigned int count = 10;
	u8 data;
	int status;

	spin_lock_init(&uc->op_lock);

	data = CCGX_RAB_UCSI_CONTROL_STOP;
	status = ccg_write(uc, CCGX_RAB_UCSI_CONTROL, &data, sizeof(data));
	if (status < 0)
		return status;

	data = CCGX_RAB_UCSI_CONTROL_START;
	status = ccg_write(uc, CCGX_RAB_UCSI_CONTROL, &data, sizeof(data));
	if (status < 0)
		return status;

	/*
	 * Flush CCGx RESPONSE queue by acking interrupts. Above ucsi control
	 * register write will push response which must be cleared.
	 */
	do {
		status = ccg_read(uc, CCGX_RAB_INTR_REG, &data, sizeof(data));
		if (status < 0)
			return status;

		if (!(data & DEV_INT))
			return 0;

		status = ccg_write(uc, CCGX_RAB_INTR_REG, &data, sizeof(data));
		if (status < 0)
			return status;

		usleep_range(10000, 11000);
	} while (--count);

	return -ETIMEDOUT;
}

static void ucsi_ccg_update_get_current_cam_cmd(struct ucsi_ccg *uc, u8 *data)
{
	u8 cam, new_cam;

	cam = data[0];
	new_cam = uc->orig[cam].linked_idx;
	uc->updated[new_cam].active_idx = cam;
	data[0] = new_cam;
}

static bool ucsi_ccg_update_altmodes(struct ucsi *ucsi,
				     struct ucsi_altmode *orig,
				     struct ucsi_altmode *updated)
{
	struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
	struct ucsi_ccg_altmode *alt, *new_alt;
	int i, j, k = 0;
	bool found = false;

	alt = uc->orig;
	new_alt = uc->updated;
	memset(uc->updated, 0, sizeof(uc->updated));

	/*
	 * Copy original connector altmodes to new structure.
	 * We need this before second loop since second loop
	 * checks for duplicate altmodes.
	 */
	for (i = 0; i < UCSI_MAX_ALTMODES; i++) {
		alt[i].svid = orig[i].svid;
		alt[i].mid = orig[i].mid;
		if (!alt[i].svid)
			break;
	}

	for (i = 0; i < UCSI_MAX_ALTMODES; i++) {
		if (!alt[i].svid)
			break;

		/* already checked and considered */
		if (alt[i].checked)
			continue;

		if (!DP_CONF_GET_PIN_ASSIGN(alt[i].mid)) {
			/* Found Non DP altmode */
			new_alt[k].svid = alt[i].svid;
			new_alt[k].mid |= alt[i].mid;
			new_alt[k].linked_idx = i;
			alt[i].linked_idx = k;
			updated[k].svid = new_alt[k].svid;
			updated[k].mid = new_alt[k].mid;
			k++;
			continue;
		}

		for (j = i + 1; j < UCSI_MAX_ALTMODES; j++) {
			if (alt[i].svid != alt[j].svid ||
			    !DP_CONF_GET_PIN_ASSIGN(alt[j].mid)) {
				continue;
			} else {
				/* Found duplicate DP mode */
				new_alt[k].svid = alt[i].svid;
				new_alt[k].mid |= alt[i].mid | alt[j].mid;
				new_alt[k].linked_idx = UCSI_MULTI_DP_INDEX;
				alt[i].linked_idx = k;
				alt[j].linked_idx = k;
				alt[j].checked = true;
				found = true;
			}
		}
		if (found) {
			uc->has_multiple_dp = true;
		} else {
			/* Didn't find any duplicate DP altmode */
			new_alt[k].svid = alt[i].svid;
			new_alt[k].mid |= alt[i].mid;
			new_alt[k].linked_idx = i;
			alt[i].linked_idx = k;
		}
		updated[k].svid = new_alt[k].svid;
		updated[k].mid = new_alt[k].mid;
		k++;
	}
	return found;
}

static void ucsi_ccg_update_set_new_cam_cmd(struct ucsi_ccg *uc,
					    struct ucsi_connector *con,
					    u64 *cmd)
{
	struct ucsi_ccg_altmode *new_port, *port;
	struct typec_altmode *alt = NULL;
	u8 new_cam, cam, pin;
	bool enter_new_mode;
	int i, j, k = 0xff;

	port = uc->orig;
	new_cam = UCSI_SET_NEW_CAM_GET_AM(*cmd);
	new_port = &uc->updated[new_cam];
	cam = new_port->linked_idx;
	enter_new_mode = UCSI_SET_NEW_CAM_ENTER(*cmd);

	/*
	 * If CAM is UCSI_MULTI_DP_INDEX then this is DP altmode
	 * with multiple DP mode. Find out CAM for best pin assignment
	 * among all DP mode. Priorite pin E->D->C after making sure
	 * the partner supports that pin.
	 */
	if (cam == UCSI_MULTI_DP_INDEX) {
		if (enter_new_mode) {
			for (i = 0; con->partner_altmode[i]; i++) {
				alt = con->partner_altmode[i];
				if (alt->svid == new_port->svid)
					break;
			}
			/*
			 * alt will always be non NULL since this is
			 * UCSI_SET_NEW_CAM command and so there will be
			 * at least one con->partner_altmode[i] with svid
			 * matching with new_port->svid.
			 */
			for (j = 0; port[j].svid; j++) {
				pin = DP_CONF_GET_PIN_ASSIGN(port[j].mid);
				if (alt && port[j].svid == alt->svid &&
				    (pin & DP_CONF_GET_PIN_ASSIGN(alt->vdo))) {
					/* prioritize pin E->D->C */
					if (k == 0xff || (k != 0xff && pin >
					    DP_CONF_GET_PIN_ASSIGN(port[k].mid))
					    ) {
						k = j;
					}
				}
			}
			cam = k;
			new_port->active_idx = cam;
		} else {
			cam = new_port->active_idx;
		}
	}
	*cmd &= ~UCSI_SET_NEW_CAM_AM_MASK;
	*cmd |= UCSI_SET_NEW_CAM_SET_AM(cam);
}

/*
 * Change the order of vdo values of NVIDIA test device FTB
 * (Function Test Board) which reports altmode list with vdo=0x3
 * first and then vdo=0x. Current logic to assign mode value is
 * based on order in altmode list and it causes a mismatch of CON
 * and SOP altmodes since NVIDIA GPU connector has order of vdo=0x1
 * first and then vdo=0x3
 */
static void ucsi_ccg_nvidia_altmode(struct ucsi_ccg *uc,
				    struct ucsi_altmode *alt)
{
	switch (UCSI_ALTMODE_OFFSET(uc->last_cmd_sent)) {
	case NVIDIA_FTB_DP_OFFSET:
		if (alt[0].mid == USB_TYPEC_NVIDIA_VLINK_DBG_VDO)
			alt[0].mid = USB_TYPEC_NVIDIA_VLINK_DP_VDO |
				     DP_CAP_DP_SIGNALLING(0) | DP_CAP_USB |
				     DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_E));
		break;
	case NVIDIA_FTB_DBG_OFFSET:
		if (alt[0].mid == USB_TYPEC_NVIDIA_VLINK_DP_VDO)
			alt[0].mid = USB_TYPEC_NVIDIA_VLINK_DBG_VDO;
		break;
	default:
		break;
	}
}

static int ucsi_ccg_read(struct ucsi *ucsi, unsigned int offset,
			 void *val, size_t val_len)
{
	struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
	u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(offset);
	struct ucsi_capability *cap;
	struct ucsi_altmode *alt;
	int ret = 0;

	if (offset == UCSI_CCI) {
		spin_lock(&uc->op_lock);
		memcpy(val, &(uc->op_data).cci, val_len);
		spin_unlock(&uc->op_lock);
	} else if (offset == UCSI_MESSAGE_IN) {
		spin_lock(&uc->op_lock);
		memcpy(val, &(uc->op_data).message_in, val_len);
		spin_unlock(&uc->op_lock);
	} else {
		ret = ccg_read(uc, reg, val, val_len);
	}

	if (ret)
		return ret;

	if (offset != UCSI_MESSAGE_IN)
		return ret;

	switch (UCSI_COMMAND(uc->last_cmd_sent)) {
	case UCSI_GET_CURRENT_CAM:
		if (uc->has_multiple_dp)
			ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)val);
		break;
	case UCSI_GET_ALTERNATE_MODES:
		if (UCSI_ALTMODE_RECIPIENT(uc->last_cmd_sent) ==
		    UCSI_RECIPIENT_SOP) {
			alt = val;
			if (alt[0].svid == USB_TYPEC_NVIDIA_VLINK_SID)
				ucsi_ccg_nvidia_altmode(uc, alt);
		}
		break;
	case UCSI_GET_CAPABILITY:
		if (uc->fw_build == CCG_FW_BUILD_NVIDIA_TEGRA) {
			cap = val;
			cap->features &= ~UCSI_CAP_ALT_MODE_DETAILS;
		}
		break;
	default:
		break;
	}
	uc->last_cmd_sent = 0;

	return ret;
}

static int ucsi_ccg_async_write(struct ucsi *ucsi, unsigned int offset,
				const void *val, size_t val_len)
{
	struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
	u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(offset);

	/*
	 * UCSI may read CCI instantly after async_write,
	 * clear CCI to avoid caller getting wrong data before we get CCI from ISR
	 */
	spin_lock(&uc->op_lock);
	uc->op_data.cci = 0;
	spin_unlock(&uc->op_lock);

	return ccg_write(uc, reg, val, val_len);
}

static int ucsi_ccg_sync_write(struct ucsi *ucsi, unsigned int offset,
			       const void *val, size_t val_len)
{
	struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi);
	struct ucsi_connector *con;
	int con_index;
	int ret;

	mutex_lock(&uc->lock);
	pm_runtime_get_sync(uc->dev);
	set_bit(DEV_CMD_PENDING, &uc->flags);

	if (offset == UCSI_CONTROL && val_len == sizeof(uc->last_cmd_sent)) {
		uc->last_cmd_sent = *(u64 *)val;

		if (UCSI_COMMAND(uc->last_cmd_sent) == UCSI_SET_NEW_CAM &&
		    uc->has_multiple_dp) {
			con_index = (uc->last_cmd_sent >> 16) &
				    UCSI_CMD_CONNECTOR_MASK;
			con = &uc->ucsi->connector[con_index - 1];
			ucsi_ccg_update_set_new_cam_cmd(uc, con, (u64 *)val);
		}
	}

	ret = ucsi_ccg_async_write(ucsi, offset, val, val_len);
	if (ret)
		goto err_clear_bit;

	if (!wait_for_completion_timeout(&uc->complete, msecs_to_jiffies(5000)))
		ret = -ETIMEDOUT;

err_clear_bit:
	clear_bit(DEV_CMD_PENDING, &uc->flags);
	pm_runtime_put_sync(uc->dev);
	mutex_unlock(&uc->lock);

	return ret;
}

static const struct ucsi_operations ucsi_ccg_ops = {
	.read = ucsi_ccg_read,
	.sync_write = ucsi_ccg_sync_write,
	.async_write = ucsi_ccg_async_write,
	.update_altmodes = ucsi_ccg_update_altmodes
};

static irqreturn_t ccg_irq_handler(int irq, void *data)
{
	u16 reg = CCGX_RAB_UCSI_DATA_BLOCK(UCSI_CCI);
	struct ucsi_ccg *uc = data;
	u8 intr_reg;
	u32 cci = 0;
	int ret = 0;

	ret = ccg_read(uc, CCGX_RAB_INTR_REG, &intr_reg, sizeof(intr_reg));
	if (ret)
		return ret;

	if (!intr_reg)
		return IRQ_HANDLED;
	else if (!(intr_reg & UCSI_READ_INT))
		goto err_clear_irq;

	ret = ccg_read(uc, reg, (void *)&cci, sizeof(cci));
	if (ret)
		goto err_clear_irq;

	if (UCSI_CCI_CONNECTOR(cci))
		ucsi_connector_change(uc->ucsi, UCSI_CCI_CONNECTOR(cci));

	/*
	 * As per CCGx UCSI interface guide, copy CCI and MESSAGE_IN
	 * to the OpRegion before clear the UCSI interrupt
	 */
	ret = ccg_op_region_update(uc, cci);
	if (ret)
		goto err_clear_irq;

err_clear_irq:
	ccg_write(uc, CCGX_RAB_INTR_REG, &intr_reg, sizeof(intr_reg));

	if (!ret && test_bit(DEV_CMD_PENDING, &uc->flags) &&
	    cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))
		complete(&uc->complete);

	return IRQ_HANDLED;
}

static int ccg_request_irq(struct ucsi_ccg *uc)
{
	unsigned long flags = IRQF_ONESHOT;

	if (!dev_fwnode(uc->dev))
		flags |= IRQF_TRIGGER_HIGH;

	return request_threaded_irq(uc->irq, NULL, ccg_irq_handler, flags, dev_name(uc->dev), uc);
}

static void ccg_pm_workaround_work(struct work_struct *pm_work)
{
	ccg_irq_handler(0, container_of(pm_work, struct ucsi_ccg, pm_work));
}

static int get_fw_info(struct ucsi_ccg *uc)
{
	int err;

	err = ccg_read(uc, CCGX_RAB_READ_ALL_VER, (u8 *)(&uc->version),
		       sizeof(uc->version));
	if (err < 0)
		return err;

	uc->fw_version = CCG_VERSION(uc->version[FW2].app.ver) |
			CCG_VERSION_PATCH(uc->version[FW2].app.patch);

	err = ccg_read(uc, CCGX_RAB_DEVICE_MODE, (u8 *)(&uc->info),
		       sizeof(uc->info));
	if (err < 0)
		return err;

	return 0;
}

static inline bool invalid_async_evt(int code)
{
	return (code >= CCG_EVENT_MAX) || (code < EVENT_INDEX);
}

static void ccg_process_response(struct ucsi_ccg *uc)
{
	struct device *dev = uc->dev;

	if (uc->dev_resp.code & ASYNC_EVENT) {
		if (uc->dev_resp.code == RESET_COMPLETE) {
			if (test_bit(RESET_PENDING, &uc->flags))
				uc->cmd_resp = uc->dev_resp.code;
			get_fw_info(uc);
		}
		if (invalid_async_evt(uc->dev_resp.code))
			dev_err(dev, "invalid async evt %d\n",
				uc->dev_resp.code);
	} else {
		if (test_bit(DEV_CMD_PENDING, &uc->flags)) {
			uc->cmd_resp = uc->dev_resp.code;
			clear_bit(DEV_CMD_PENDING, &uc->flags);
		} else {
			dev_err(dev, "dev resp 0x%04x but no cmd pending\n",
				uc->dev_resp.code);
		}
	}
}

static int ccg_read_response(struct ucsi_ccg *uc)
{
	unsigned long target = jiffies + msecs_to_jiffies(1000);
	struct device *dev = uc->dev;
	u8 intval;
	int status;

	/* wait for interrupt status to get updated */
	do {
		status = ccg_read(uc, CCGX_RAB_INTR_REG, &intval,
				  sizeof(intval));
		if (status < 0)
			return status;

		if (intval & DEV_INT)
			break;
		usleep_range(500, 600);
	} while (time_is_after_jiffies(target));

	if (time_is_before_jiffies(target)) {
		dev_err(dev, "response timeout error\n");
		return -ETIME;
	}

	status = ccg_read(uc, CCGX_RAB_RESPONSE, (u8 *)&uc->dev_resp,
			  sizeof(uc->dev_resp));
	if (status < 0)
		return status;

	status = ccg_write(uc, CCGX_RAB_INTR_REG, &intval, sizeof(intval));
	if (status < 0)
		return status;

	return 0;
}

/* Caller must hold uc->lock */
static int ccg_send_command(struct ucsi_ccg *uc, struct ccg_cmd *cmd)
{
	struct device *dev = uc->dev;
	int ret;

	switch (cmd->reg & 0xF000) {
	case DEV_REG_IDX:
		set_bit(DEV_CMD_PENDING, &uc->flags);
		break;
	default:
		dev_err(dev, "invalid cmd register\n");
		break;
	}

	ret = ccg_write(uc, cmd->reg, (u8 *)&cmd->data, cmd->len);
	if (ret < 0)
		return ret;

	msleep(cmd->delay);

	ret = ccg_read_response(uc);
	if (ret < 0) {
		dev_err(dev, "response read error\n");
		switch (cmd->reg & 0xF000) {
		case DEV_REG_IDX:
			clear_bit(DEV_CMD_PENDING, &uc->flags);
			break;
		default:
			dev_err(dev, "invalid cmd register\n");
			break;
		}
		return -EIO;
	}
	ccg_process_response(uc);

	return uc->cmd_resp;
}

static int ccg_cmd_enter_flashing(struct ucsi_ccg *uc)
{
	struct ccg_cmd cmd;
	int ret;

	cmd.reg = CCGX_RAB_ENTER_FLASHING;
	cmd.data = FLASH_ENTER_SIG;
	cmd.len = 1;
	cmd.delay = 50;

	mutex_lock(&uc->lock);

	ret = ccg_send_command(uc, &cmd);

	mutex_unlock(&uc->lock);

	if (ret != CMD_SUCCESS) {
		dev_err(uc->dev, "enter flashing failed ret=%d\n", ret);
		return ret;
	}

	return 0;
}

static int ccg_cmd_reset(struct ucsi_ccg *uc)
{
	struct ccg_cmd cmd;
	u8 *p;
	int ret;

	p = (u8 *)&cmd.data;
	cmd.reg = CCGX_RAB_RESET_REQ;
	p[0] = RESET_SIG;
	p[1] = CMD_RESET_DEV;
	cmd.len = 2;
	cmd.delay = 5000;

	mutex_lock(&uc->lock);

	set_bit(RESET_PENDING, &uc->flags);

	ret = ccg_send_command(uc, &cmd);
	if (ret != RESET_COMPLETE)
		goto err_clear_flag;

	ret = 0;

err_clear_flag:
	clear_bit(RESET_PENDING, &uc->flags);

	mutex_unlock(&uc->lock);

	return ret;
}

static int ccg_cmd_port_control(struct ucsi_ccg *uc, bool enable)
{
	struct ccg_cmd cmd;
	int ret;

	cmd.reg = CCGX_RAB_PDPORT_ENABLE;
	if (enable)
		cmd.data = (uc->port_num == 1) ?
			    PDPORT_1 : (PDPORT_1 | PDPORT_2);
	else
		cmd.data = 0x0;
	cmd.len = 1;
	cmd.delay = 10;

	mutex_lock(&uc->lock);

	ret = ccg_send_command(uc, &cmd);

	mutex_unlock(&uc->lock);

	if (ret != CMD_SUCCESS) {
		dev_err(uc->dev, "port control failed ret=%d\n", ret);
		return ret;
	}
	return 0;
}

static int ccg_cmd_jump_boot_mode(struct ucsi_ccg *uc, int bl_mode)
{
	struct ccg_cmd cmd;
	int ret;

	cmd.reg = CCGX_RAB_JUMP_TO_BOOT;

	if (bl_mode)
		cmd.data = TO_BOOT;
	else
		cmd.data = TO_ALT_FW;

	cmd.len = 1;
	cmd.delay = 100;

	mutex_lock(&uc->lock);

	set_bit(RESET_PENDING, &uc->flags);

	ret = ccg_send_command(uc, &cmd);
	if (ret != RESET_COMPLETE)
		goto err_clear_flag;

	ret = 0;

err_clear_flag:
	clear_bit(RESET_PENDING, &uc->flags);

	mutex_unlock(&uc->lock);

	return ret;
}

static int
ccg_cmd_write_flash_row(struct ucsi_ccg *uc, u16 row,
			const void *data, u8 fcmd)
{
	struct i2c_client *client = uc->client;
	struct ccg_cmd cmd;
	u8 buf[CCG4_ROW_SIZE + 2];
	u8 *p;
	int ret;

	/* Copy the data into the flash read/write memory. */
	put_unaligned_le16(REG_FLASH_RW_MEM, buf);

	memcpy(buf + 2, data, CCG4_ROW_SIZE);

	mutex_lock(&uc->lock);

	ret = i2c_master_send(client, buf, CCG4_ROW_SIZE + 2);
	if (ret != CCG4_ROW_SIZE + 2) {
		dev_err(uc->dev, "REG_FLASH_RW_MEM write fail %d\n", ret);
		mutex_unlock(&uc->lock);
		return ret < 0 ? ret : -EIO;
	}

	/* Use the FLASH_ROW_READ_WRITE register to trigger */
	/* writing of data to the desired flash row */
	p = (u8 *)&cmd.data;
	cmd.reg = CCGX_RAB_FLASH_ROW_RW;
	p[0] = FLASH_SIG;
	p[1] = fcmd;
	put_unaligned_le16(row, &p[2]);
	cmd.len = 4;
	cmd.delay = 50;
	if (fcmd == FLASH_FWCT_SIG_WR_CMD)
		cmd.delay += 400;
	if (row == 510)
		cmd.delay += 220;
	ret = ccg_send_command(uc, &cmd);

	mutex_unlock(&uc->lock);

	if (ret != CMD_SUCCESS) {
		dev_err(uc->dev, "write flash row failed ret=%d\n", ret);
		return ret;
	}

	return 0;
}

static int ccg_cmd_validate_fw(struct ucsi_ccg *uc, unsigned int fwid)
{
	struct ccg_cmd cmd;
	int ret;

	cmd.reg = CCGX_RAB_VALIDATE_FW;
	cmd.data = fwid;
	cmd.len = 1;
	cmd.delay = 500;

	mutex_lock(&uc->lock);

	ret = ccg_send_command(uc, &cmd);

	mutex_unlock(&uc->lock);

	if (ret != CMD_SUCCESS)
		return ret;

	return 0;
}

static bool ccg_check_vendor_version(struct ucsi_ccg *uc,
				     struct version_format *app,
				     struct fw_config_table *fw_cfg)
{
	struct device *dev = uc->dev;

	/* Check if the fw build is for supported vendors */
	if (le16_to_cpu(app->build) != uc->fw_build) {
		dev_info(dev, "current fw is not from supported vendor\n");
		return false;
	}

	/* Check if the new fw build is for supported vendors */
	if (le16_to_cpu(fw_cfg->app.build) != uc->fw_build) {
		dev_info(dev, "new fw is not from supported vendor\n");
		return false;
	}
	return true;
}

static bool ccg_check_fw_version(struct ucsi_ccg *uc, const char *fw_name,
				 struct version_format *app)
{
	const struct firmware *fw = NULL;
	struct device *dev = uc->dev;
	struct fw_config_table fw_cfg;
	u32 cur_version, new_version;
	bool is_later = false;

	if (request_firmware(&fw, fw_name, dev) != 0) {
		dev_err(dev, "error: Failed to open cyacd file %s\n", fw_name);
		return false;
	}

	/*
	 * check if signed fw
	 * last part of fw image is fw cfg table and signature
	 */
	if (fw->size < sizeof(fw_cfg) + FW_CFG_TABLE_SIG_SIZE)
		goto out_release_firmware;

	memcpy((uint8_t *)&fw_cfg, fw->data + fw->size -
	       sizeof(fw_cfg) - FW_CFG_TABLE_SIG_SIZE, sizeof(fw_cfg));

	if (fw_cfg.identity != ('F' | 'W' << 8 | 'C' << 16 | 'T' << 24)) {
		dev_info(dev, "not a signed image\n");
		goto out_release_firmware;
	}

	/* compare input version with FWCT version */
	cur_version = le16_to_cpu(app->build) | CCG_VERSION_PATCH(app->patch) |
			CCG_VERSION(app->ver);

	new_version = le16_to_cpu(fw_cfg.app.build) |
			CCG_VERSION_PATCH(fw_cfg.app.patch) |
			CCG_VERSION(fw_cfg.app.ver);

	if (!ccg_check_vendor_version(uc, app, &fw_cfg))
		goto out_release_firmware;

	if (new_version > cur_version)
		is_later = true;

out_release_firmware:
	release_firmware(fw);
	return is_later;
}

static int ccg_fw_update_needed(struct ucsi_ccg *uc,
				enum enum_flash_mode *mode)
{
	struct device *dev = uc->dev;
	int err;
	struct version_info version[3];

	err = ccg_read(uc, CCGX_RAB_DEVICE_MODE, (u8 *)(&uc->info),
		       sizeof(uc->info));
	if (err) {
		dev_err(dev, "read device mode failed\n");
		return err;
	}

	err = ccg_read(uc, CCGX_RAB_READ_ALL_VER, (u8 *)version,
		       sizeof(version));
	if (err) {
		dev_err(dev, "read device mode failed\n");
		return err;
	}

	if (memcmp(&version[FW1], "\0\0\0\0\0\0\0\0",
		   sizeof(struct version_info)) == 0) {
		dev_info(dev, "secondary fw is not flashed\n");
		*mode = SECONDARY_BL;
	} else if (le16_to_cpu(version[FW1].base.build) <
		secondary_fw_min_ver) {
		dev_info(dev, "secondary fw version is too low (< %d)\n",
			 secondary_fw_min_ver);
		*mode = SECONDARY;
	} else if (memcmp(&version[FW2], "\0\0\0\0\0\0\0\0",
		   sizeof(struct version_info)) == 0) {
		dev_info(dev, "primary fw is not flashed\n");
		*mode = PRIMARY;
	} else if (ccg_check_fw_version(uc, ccg_fw_names[PRIMARY],
		   &version[FW2].app)) {
		dev_info(dev, "found primary fw with later version\n");
		*mode = PRIMARY;
	} else {
		dev_info(dev, "secondary and primary fw are the latest\n");
		*mode = FLASH_NOT_NEEDED;
	}
	return 0;
}

static int do_flash(struct ucsi_ccg *uc, enum enum_flash_mode mode)
{
	struct device *dev = uc->dev;
	const struct firmware *fw = NULL;
	const char *p, *s;
	const char *eof;
	int err, row, len, line_sz, line_cnt = 0;
	unsigned long start_time = jiffies;
	struct fw_config_table  fw_cfg;
	u8 fw_cfg_sig[FW_CFG_TABLE_SIG_SIZE];
	u8 *wr_buf;

	err = request_firmware(&fw, ccg_fw_names[mode], dev);
	if (err) {
		dev_err(dev, "request %s failed err=%d\n",
			ccg_fw_names[mode], err);
		return err;
	}

	if (((uc->info.mode & CCG_DEVINFO_FWMODE_MASK) >>
			CCG_DEVINFO_FWMODE_SHIFT) == FW2) {
		err = ccg_cmd_port_control(uc, false);
		if (err < 0)
			goto release_fw;
		err = ccg_cmd_jump_boot_mode(uc, 0);
		if (err < 0)
			goto release_fw;
	}

	eof = fw->data + fw->size;

	/*
	 * check if signed fw
	 * last part of fw image is fw cfg table and signature
	 */
	if (fw->size < sizeof(fw_cfg) + sizeof(fw_cfg_sig))
		goto not_signed_fw;

	memcpy((uint8_t *)&fw_cfg, fw->data + fw->size -
	       sizeof(fw_cfg) - sizeof(fw_cfg_sig), sizeof(fw_cfg));

	if (fw_cfg.identity != ('F' | ('W' << 8) | ('C' << 16) | ('T' << 24))) {
		dev_info(dev, "not a signed image\n");
		goto not_signed_fw;
	}
	eof = fw->data + fw->size - sizeof(fw_cfg) - sizeof(fw_cfg_sig);

	memcpy((uint8_t *)&fw_cfg_sig,
	       fw->data + fw->size - sizeof(fw_cfg_sig), sizeof(fw_cfg_sig));

	/* flash fw config table and signature first */
	err = ccg_cmd_write_flash_row(uc, 0, (u8 *)&fw_cfg,
				      FLASH_FWCT1_WR_CMD);
	if (err)
		goto release_fw;

	err = ccg_cmd_write_flash_row(uc, 0, (u8 *)&fw_cfg + CCG4_ROW_SIZE,
				      FLASH_FWCT2_WR_CMD);
	if (err)
		goto release_fw;

	err = ccg_cmd_write_flash_row(uc, 0, &fw_cfg_sig,
				      FLASH_FWCT_SIG_WR_CMD);
	if (err)
		goto release_fw;

not_signed_fw:
	wr_buf = kzalloc(CCG4_ROW_SIZE + 4, GFP_KERNEL);
	if (!wr_buf) {
		err = -ENOMEM;
		goto release_fw;
	}

	err = ccg_cmd_enter_flashing(uc);
	if (err)
		goto release_mem;

	/*****************************************************************
	 * CCG firmware image (.cyacd) file line format
	 *
	 * :00rrrrllll[dd....]cc/r/n
	 *
	 * :00   header
	 * rrrr is row number to flash				(4 char)
	 * llll is data len to flash				(4 char)
	 * dd   is a data field represents one byte of data	(512 char)
	 * cc   is checksum					(2 char)
	 * \r\n newline
	 *
	 * Total length: 3 + 4 + 4 + 512 + 2 + 2 = 527
	 *
	 *****************************************************************/

	p = strnchr(fw->data, fw->size, ':');
	while (p < eof) {
		s = strnchr(p + 1, eof - p - 1, ':');

		if (!s)
			s = eof;

		line_sz = s - p;

		if (line_sz != CYACD_LINE_SIZE) {
			dev_err(dev, "Bad FW format line_sz=%d\n", line_sz);
			err =  -EINVAL;
			goto release_mem;
		}

		if (hex2bin(wr_buf, p + 3, CCG4_ROW_SIZE + 4)) {
			err =  -EINVAL;
			goto release_mem;
		}

		row = get_unaligned_be16(wr_buf);
		len = get_unaligned_be16(&wr_buf[2]);

		if (len != CCG4_ROW_SIZE) {
			err =  -EINVAL;
			goto release_mem;
		}

		err = ccg_cmd_write_flash_row(uc, row, wr_buf + 4,
					      FLASH_WR_CMD);
		if (err)
			goto release_mem;

		line_cnt++;
		p = s;
	}

	dev_info(dev, "total %d row flashed. time: %dms\n",
		 line_cnt, jiffies_to_msecs(jiffies - start_time));

	err = ccg_cmd_validate_fw(uc, (mode == PRIMARY) ? FW2 :  FW1);
	if (err)
		dev_err(dev, "%s validation failed err=%d\n",
			(mode == PRIMARY) ? "FW2" :  "FW1", err);
	else
		dev_info(dev, "%s validated\n",
			 (mode == PRIMARY) ? "FW2" :  "FW1");

	err = ccg_cmd_port_control(uc, false);
	if (err < 0)
		goto release_mem;

	err = ccg_cmd_reset(uc);
	if (err < 0)
		goto release_mem;

	err = ccg_cmd_port_control(uc, true);
	if (err < 0)
		goto release_mem;

release_mem:
	kfree(wr_buf);

release_fw:
	release_firmware(fw);
	return err;
}

/*******************************************************************************
 * CCG4 has two copies of the firmware in addition to the bootloader.
 * If the device is running FW1, FW2 can be updated with the new version.
 * Dual firmware mode allows the CCG device to stay in a PD contract and support
 * USB PD and Type-C functionality while a firmware update is in progress.
 ******************************************************************************/
static int ccg_fw_update(struct ucsi_ccg *uc, enum enum_flash_mode flash_mode)
{
	int err = 0;

	while (flash_mode != FLASH_NOT_NEEDED) {
		err = do_flash(uc, flash_mode);
		if (err < 0)
			return err;
		err = ccg_fw_update_needed(uc, &flash_mode);
		if (err < 0)
			return err;
	}
	dev_info(uc->dev, "CCG FW update successful\n");

	return err;
}

static int ccg_restart(struct ucsi_ccg *uc)
{
	struct device *dev = uc->dev;
	int status;

	status = ucsi_ccg_init(uc);
	if (status < 0) {
		dev_err(dev, "ucsi_ccg_start fail, err=%d\n", status);
		return status;
	}

	status = ccg_request_irq(uc);
	if (status < 0) {
		dev_err(dev, "request_threaded_irq failed - %d\n", status);
		return status;
	}

	status = ucsi_register(uc->ucsi);
	if (status) {
		dev_err(uc->dev, "failed to register the interface\n");
		return status;
	}

	pm_runtime_enable(uc->dev);
	return 0;
}

static void ccg_update_firmware(struct work_struct *work)
{
	struct ucsi_ccg *uc = container_of(work, struct ucsi_ccg, work);
	enum enum_flash_mode flash_mode;
	int status;

	status = ccg_fw_update_needed(uc, &flash_mode);
	if (status < 0)
		return;

	if (flash_mode != FLASH_NOT_NEEDED) {
		ucsi_unregister(uc->ucsi);
		pm_runtime_disable(uc->dev);
		free_irq(uc->irq, uc);

		ccg_fw_update(uc, flash_mode);
		ccg_restart(uc);
	}
}

static ssize_t do_flash_store(struct device *dev,
			      struct device_attribute *attr,
			      const char *buf, size_t n)
{
	struct ucsi_ccg *uc = i2c_get_clientdata(to_i2c_client(dev));
	bool flash;

	if (kstrtobool(buf, &flash))
		return -EINVAL;

	if (!flash)
		return n;

	if (uc->fw_build == 0x0) {
		dev_err(dev, "fail to flash FW due to missing FW build info\n");
		return -EINVAL;
	}

	schedule_work(&uc->work);
	return n;
}

static DEVICE_ATTR_WO(do_flash);

static struct attribute *ucsi_ccg_attrs[] = {
	&dev_attr_do_flash.attr,
	NULL,
};
ATTRIBUTE_GROUPS(ucsi_ccg);

static int ucsi_ccg_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct ucsi_ccg *uc;
	const char *fw_name;
	int status;

	uc = devm_kzalloc(dev, sizeof(*uc), GFP_KERNEL);
	if (!uc)
		return -ENOMEM;

	uc->dev = dev;
	uc->client = client;
	uc->irq = client->irq;
	mutex_init(&uc->lock);
	init_completion(&uc->complete);
	INIT_WORK(&uc->work, ccg_update_firmware);
	INIT_WORK(&uc->pm_work, ccg_pm_workaround_work);

	/* Only fail FW flashing when FW build information is not provided */
	status = device_property_read_string(dev, "firmware-name", &fw_name);
	if (!status) {
		if (!strcmp(fw_name, "nvidia,jetson-agx-xavier"))
			uc->fw_build = CCG_FW_BUILD_NVIDIA_TEGRA;
		else if (!strcmp(fw_name, "nvidia,gpu"))
			uc->fw_build = CCG_FW_BUILD_NVIDIA;
	}

	if (!uc->fw_build)
		dev_err(uc->dev, "failed to get FW build information\n");

	/* reset ccg device and initialize ucsi */
	status = ucsi_ccg_init(uc);
	if (status < 0) {
		dev_err(uc->dev, "ucsi_ccg_init failed - %d\n", status);
		return status;
	}

	status = get_fw_info(uc);
	if (status < 0) {
		dev_err(uc->dev, "get_fw_info failed - %d\n", status);
		return status;
	}

	uc->port_num = 1;

	if (uc->info.mode & CCG_DEVINFO_PDPORTS_MASK)
		uc->port_num++;

	uc->ucsi = ucsi_create(dev, &ucsi_ccg_ops);
	if (IS_ERR(uc->ucsi))
		return PTR_ERR(uc->ucsi);

	ucsi_set_drvdata(uc->ucsi, uc);

	status = ccg_request_irq(uc);
	if (status < 0) {
		dev_err(uc->dev, "request_threaded_irq failed - %d\n", status);
		goto out_ucsi_destroy;
	}

	status = ucsi_register(uc->ucsi);
	if (status)
		goto out_free_irq;

	i2c_set_clientdata(client, uc);

	pm_runtime_set_active(uc->dev);
	pm_runtime_enable(uc->dev);
	pm_runtime_use_autosuspend(uc->dev);
	pm_runtime_set_autosuspend_delay(uc->dev, 5000);
	pm_runtime_idle(uc->dev);

	return 0;

out_free_irq:
	free_irq(uc->irq, uc);
out_ucsi_destroy:
	ucsi_destroy(uc->ucsi);

	return status;
}

static void ucsi_ccg_remove(struct i2c_client *client)
{
	struct ucsi_ccg *uc = i2c_get_clientdata(client);

	cancel_work_sync(&uc->pm_work);
	cancel_work_sync(&uc->work);
	pm_runtime_disable(uc->dev);
	ucsi_unregister(uc->ucsi);
	ucsi_destroy(uc->ucsi);
	free_irq(uc->irq, uc);
}

static const struct of_device_id ucsi_ccg_of_match_table[] = {
		{ .compatible = "cypress,cypd4226", },
		{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ucsi_ccg_of_match_table);

static const struct i2c_device_id ucsi_ccg_device_id[] = {
	{"ccgx-ucsi", 0},
	{}
};
MODULE_DEVICE_TABLE(i2c, ucsi_ccg_device_id);

static const struct acpi_device_id amd_i2c_ucsi_match[] = {
	{"AMDI0042"},
	{}
};
MODULE_DEVICE_TABLE(acpi, amd_i2c_ucsi_match);

static int ucsi_ccg_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ucsi_ccg *uc = i2c_get_clientdata(client);

	return ucsi_resume(uc->ucsi);
}

static int ucsi_ccg_runtime_suspend(struct device *dev)
{
	return 0;
}

static int ucsi_ccg_runtime_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ucsi_ccg *uc = i2c_get_clientdata(client);

	/*
	 * Firmware version 3.1.10 or earlier, built for NVIDIA has known issue
	 * of missing interrupt when a device is connected for runtime resume.
	 * Schedule a work to call ISR as a workaround.
	 */
	if (uc->fw_build == CCG_FW_BUILD_NVIDIA &&
	    uc->fw_version <= CCG_OLD_FW_VERSION)
		schedule_work(&uc->pm_work);

	return 0;
}

static const struct dev_pm_ops ucsi_ccg_pm = {
	.resume = ucsi_ccg_resume,
	.runtime_suspend = ucsi_ccg_runtime_suspend,
	.runtime_resume = ucsi_ccg_runtime_resume,
};

static struct i2c_driver ucsi_ccg_driver = {
	.driver = {
		.name = "ucsi_ccg",
		.pm = &ucsi_ccg_pm,
		.dev_groups = ucsi_ccg_groups,
		.acpi_match_table = amd_i2c_ucsi_match,
		.of_match_table = ucsi_ccg_of_match_table,
	},
	.probe = ucsi_ccg_probe,
	.remove = ucsi_ccg_remove,
	.id_table = ucsi_ccg_device_id,
};

module_i2c_driver(ucsi_ccg_driver);

MODULE_AUTHOR("Ajay Gupta <ajayg@nvidia.com>");
MODULE_DESCRIPTION("UCSI driver for Cypress CCGx Type-C controller");
MODULE_LICENSE("GPL v2");
