// SPDX-License-Identifier: GPL-2.0-only
/*
 * MCP2221A - Microchip USB to I2C Host Protocol Bridge
 *
 * Copyright (c) 2020, Rishi Gupta <gupt21@gmail.com>
 *
 * Datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/20005565B.pdf
 */

#include <linux/module.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/hid.h>
#include <linux/hidraw.h>
#include <linux/i2c.h>
#include <linux/gpio/driver.h>
#include "hid-ids.h"

/* Commands codes in a raw output report */
enum {
	MCP2221_I2C_WR_DATA = 0x90,
	MCP2221_I2C_WR_NO_STOP = 0x94,
	MCP2221_I2C_RD_DATA = 0x91,
	MCP2221_I2C_RD_RPT_START = 0x93,
	MCP2221_I2C_GET_DATA = 0x40,
	MCP2221_I2C_PARAM_OR_STATUS	= 0x10,
	MCP2221_I2C_SET_SPEED = 0x20,
	MCP2221_I2C_CANCEL = 0x10,
	MCP2221_GPIO_SET = 0x50,
	MCP2221_GPIO_GET = 0x51,
};

/* Response codes in a raw input report */
enum {
	MCP2221_SUCCESS = 0x00,
	MCP2221_I2C_ENG_BUSY = 0x01,
	MCP2221_I2C_START_TOUT = 0x12,
	MCP2221_I2C_STOP_TOUT = 0x62,
	MCP2221_I2C_WRADDRL_TOUT = 0x23,
	MCP2221_I2C_WRDATA_TOUT = 0x44,
	MCP2221_I2C_WRADDRL_NACK = 0x25,
	MCP2221_I2C_MASK_ADDR_NACK = 0x40,
	MCP2221_I2C_WRADDRL_SEND = 0x21,
	MCP2221_I2C_ADDR_NACK = 0x25,
	MCP2221_I2C_READ_COMPL = 0x55,
	MCP2221_ALT_F_NOT_GPIOV = 0xEE,
	MCP2221_ALT_F_NOT_GPIOD = 0xEF,
};

/* MCP GPIO direction encoding */
enum {
	MCP2221_DIR_OUT = 0x00,
	MCP2221_DIR_IN = 0x01,
};

#define MCP_NGPIO	4

/* MCP GPIO set command layout */
struct mcp_set_gpio {
	u8 cmd;
	u8 dummy;
	struct {
		u8 change_value;
		u8 value;
		u8 change_direction;
		u8 direction;
	} gpio[MCP_NGPIO];
} __packed;

/* MCP GPIO get command layout */
struct mcp_get_gpio {
	u8 cmd;
	u8 dummy;
	struct {
		u8 direction;
		u8 value;
	} gpio[MCP_NGPIO];
} __packed;

/*
 * There is no way to distinguish responses. Therefore next command
 * is sent only after response to previous has been received. Mutex
 * lock is used for this purpose mainly.
 */
struct mcp2221 {
	struct hid_device *hdev;
	struct i2c_adapter adapter;
	struct mutex lock;
	struct completion wait_in_report;
	u8 *rxbuf;
	u8 txbuf[64];
	int rxbuf_idx;
	int status;
	u8 cur_i2c_clk_div;
	struct gpio_chip *gc;
	u8 gp_idx;
	u8 gpio_dir;
};

/*
 * Default i2c bus clock frequency 400 kHz. Modify this if you
 * want to set some other frequency (min 50 kHz - max 400 kHz).
 */
static uint i2c_clk_freq = 400;

/* Synchronously send output report to the device */
static int mcp_send_report(struct mcp2221 *mcp,
					u8 *out_report, size_t len)
{
	u8 *buf;
	int ret;

	buf = kmemdup(out_report, len, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	/* mcp2221 uses interrupt endpoint for out reports */
	ret = hid_hw_output_report(mcp->hdev, buf, len);
	kfree(buf);

	if (ret < 0)
		return ret;
	return 0;
}

/*
 * Send o/p report to the device and wait for i/p report to be
 * received from the device. If the device does not respond,
 * we timeout.
 */
static int mcp_send_data_req_status(struct mcp2221 *mcp,
			u8 *out_report, int len)
{
	int ret;
	unsigned long t;

	reinit_completion(&mcp->wait_in_report);

	ret = mcp_send_report(mcp, out_report, len);
	if (ret)
		return ret;

	t = wait_for_completion_timeout(&mcp->wait_in_report,
							msecs_to_jiffies(4000));
	if (!t)
		return -ETIMEDOUT;

	return mcp->status;
}

/* Check pass/fail for actual communication with i2c slave */
static int mcp_chk_last_cmd_status(struct mcp2221 *mcp)
{
	memset(mcp->txbuf, 0, 8);
	mcp->txbuf[0] = MCP2221_I2C_PARAM_OR_STATUS;

	return mcp_send_data_req_status(mcp, mcp->txbuf, 8);
}

/* Cancels last command releasing i2c bus just in case occupied */
static int mcp_cancel_last_cmd(struct mcp2221 *mcp)
{
	memset(mcp->txbuf, 0, 8);
	mcp->txbuf[0] = MCP2221_I2C_PARAM_OR_STATUS;
	mcp->txbuf[2] = MCP2221_I2C_CANCEL;

	return mcp_send_data_req_status(mcp, mcp->txbuf, 8);
}

static int mcp_set_i2c_speed(struct mcp2221 *mcp)
{
	int ret;

	memset(mcp->txbuf, 0, 8);
	mcp->txbuf[0] = MCP2221_I2C_PARAM_OR_STATUS;
	mcp->txbuf[3] = MCP2221_I2C_SET_SPEED;
	mcp->txbuf[4] = mcp->cur_i2c_clk_div;

	ret = mcp_send_data_req_status(mcp, mcp->txbuf, 8);
	if (ret) {
		/* Small delay is needed here */
		usleep_range(980, 1000);
		mcp_cancel_last_cmd(mcp);
	}

	return 0;
}

/*
 * An output report can contain minimum 1 and maximum 60 user data
 * bytes. If the number of data bytes is more then 60, we send it
 * in chunks of 60 bytes. Last chunk may contain exactly 60 or less
 * bytes. Total number of bytes is informed in very first report to
 * mcp2221, from that point onwards it first collect all the data
 * from host and then send to i2c slave device.
 */
static int mcp_i2c_write(struct mcp2221 *mcp,
				struct i2c_msg *msg, int type, u8 last_status)
{
	int ret, len, idx, sent;

	idx = 0;
	sent  = 0;
	if (msg->len < 60)
		len = msg->len;
	else
		len = 60;

	do {
		mcp->txbuf[0] = type;
		mcp->txbuf[1] = msg->len & 0xff;
		mcp->txbuf[2] = msg->len >> 8;
		mcp->txbuf[3] = (u8)(msg->addr << 1);

		memcpy(&mcp->txbuf[4], &msg->buf[idx], len);

		ret = mcp_send_data_req_status(mcp, mcp->txbuf, len + 4);
		if (ret)
			return ret;

		usleep_range(980, 1000);

		if (last_status) {
			ret = mcp_chk_last_cmd_status(mcp);
			if (ret)
				return ret;
		}

		sent = sent + len;
		if (sent >= msg->len)
			break;

		idx = idx + len;
		if ((msg->len - sent) < 60)
			len = msg->len - sent;
		else
			len = 60;

		/*
		 * Testing shows delay is needed between successive writes
		 * otherwise next write fails on first-try from i2c core.
		 * This value is obtained through automated stress testing.
		 */
		usleep_range(980, 1000);
	} while (len > 0);

	return ret;
}

/*
 * Device reads all data (0 - 65535 bytes) from i2c slave device and
 * stores it in device itself. This data is read back from device to
 * host in multiples of 60 bytes using input reports.
 */
static int mcp_i2c_smbus_read(struct mcp2221 *mcp,
				struct i2c_msg *msg, int type, u16 smbus_addr,
				u8 smbus_len, u8 *smbus_buf)
{
	int ret;
	u16 total_len;

	mcp->txbuf[0] = type;
	if (msg) {
		mcp->txbuf[1] = msg->len & 0xff;
		mcp->txbuf[2] = msg->len >> 8;
		mcp->txbuf[3] = (u8)(msg->addr << 1);
		total_len = msg->len;
		mcp->rxbuf = msg->buf;
	} else {
		mcp->txbuf[1] = smbus_len;
		mcp->txbuf[2] = 0;
		mcp->txbuf[3] = (u8)(smbus_addr << 1);
		total_len = smbus_len;
		mcp->rxbuf = smbus_buf;
	}

	ret = mcp_send_data_req_status(mcp, mcp->txbuf, 4);
	if (ret)
		return ret;

	mcp->rxbuf_idx = 0;

	do {
		memset(mcp->txbuf, 0, 4);
		mcp->txbuf[0] = MCP2221_I2C_GET_DATA;

		ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
		if (ret)
			return ret;

		ret = mcp_chk_last_cmd_status(mcp);
		if (ret)
			return ret;

		usleep_range(980, 1000);
	} while (mcp->rxbuf_idx < total_len);

	return ret;
}

static int mcp_i2c_xfer(struct i2c_adapter *adapter,
				struct i2c_msg msgs[], int num)
{
	int ret;
	struct mcp2221 *mcp = i2c_get_adapdata(adapter);

	hid_hw_power(mcp->hdev, PM_HINT_FULLON);

	mutex_lock(&mcp->lock);

	/* Setting speed before every transaction is required for mcp2221 */
	ret = mcp_set_i2c_speed(mcp);
	if (ret)
		goto exit;

	if (num == 1) {
		if (msgs->flags & I2C_M_RD) {
			ret = mcp_i2c_smbus_read(mcp, msgs, MCP2221_I2C_RD_DATA,
							0, 0, NULL);
		} else {
			ret = mcp_i2c_write(mcp, msgs, MCP2221_I2C_WR_DATA, 1);
		}
		if (ret)
			goto exit;
		ret = num;
	} else if (num == 2) {
		/* Ex transaction; send reg address and read its contents */
		if (msgs[0].addr == msgs[1].addr &&
			!(msgs[0].flags & I2C_M_RD) &&
			 (msgs[1].flags & I2C_M_RD)) {

			ret = mcp_i2c_write(mcp, &msgs[0],
						MCP2221_I2C_WR_NO_STOP, 0);
			if (ret)
				goto exit;

			ret = mcp_i2c_smbus_read(mcp, &msgs[1],
						MCP2221_I2C_RD_RPT_START,
						0, 0, NULL);
			if (ret)
				goto exit;
			ret = num;
		} else {
			dev_err(&adapter->dev,
				"unsupported multi-msg i2c transaction\n");
			ret = -EOPNOTSUPP;
		}
	} else {
		dev_err(&adapter->dev,
			"unsupported multi-msg i2c transaction\n");
		ret = -EOPNOTSUPP;
	}

exit:
	hid_hw_power(mcp->hdev, PM_HINT_NORMAL);
	mutex_unlock(&mcp->lock);
	return ret;
}

static int mcp_smbus_write(struct mcp2221 *mcp, u16 addr,
				u8 command, u8 *buf, u8 len, int type,
				u8 last_status)
{
	int data_len, ret;

	mcp->txbuf[0] = type;
	mcp->txbuf[1] = len + 1; /* 1 is due to command byte itself */
	mcp->txbuf[2] = 0;
	mcp->txbuf[3] = (u8)(addr << 1);
	mcp->txbuf[4] = command;

	switch (len) {
	case 0:
		data_len = 5;
		break;
	case 1:
		mcp->txbuf[5] = buf[0];
		data_len = 6;
		break;
	case 2:
		mcp->txbuf[5] = buf[0];
		mcp->txbuf[6] = buf[1];
		data_len = 7;
		break;
	default:
		memcpy(&mcp->txbuf[5], buf, len);
		data_len = len + 5;
	}

	ret = mcp_send_data_req_status(mcp, mcp->txbuf, data_len);
	if (ret)
		return ret;

	if (last_status) {
		usleep_range(980, 1000);

		ret = mcp_chk_last_cmd_status(mcp);
		if (ret)
			return ret;
	}

	return ret;
}

static int mcp_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
				unsigned short flags, char read_write,
				u8 command, int size,
				union i2c_smbus_data *data)
{
	int ret;
	struct mcp2221 *mcp = i2c_get_adapdata(adapter);

	hid_hw_power(mcp->hdev, PM_HINT_FULLON);

	mutex_lock(&mcp->lock);

	ret = mcp_set_i2c_speed(mcp);
	if (ret)
		goto exit;

	switch (size) {

	case I2C_SMBUS_QUICK:
		if (read_write == I2C_SMBUS_READ)
			ret = mcp_i2c_smbus_read(mcp, NULL, MCP2221_I2C_RD_DATA,
						addr, 0, &data->byte);
		else
			ret = mcp_smbus_write(mcp, addr, command, NULL,
						0, MCP2221_I2C_WR_DATA, 1);
		break;
	case I2C_SMBUS_BYTE:
		if (read_write == I2C_SMBUS_READ)
			ret = mcp_i2c_smbus_read(mcp, NULL, MCP2221_I2C_RD_DATA,
						addr, 1, &data->byte);
		else
			ret = mcp_smbus_write(mcp, addr, command, NULL,
						0, MCP2221_I2C_WR_DATA, 1);
		break;
	case I2C_SMBUS_BYTE_DATA:
		if (read_write == I2C_SMBUS_READ) {
			ret = mcp_smbus_write(mcp, addr, command, NULL,
						0, MCP2221_I2C_WR_NO_STOP, 0);
			if (ret)
				goto exit;

			ret = mcp_i2c_smbus_read(mcp, NULL,
						MCP2221_I2C_RD_RPT_START,
						addr, 1, &data->byte);
		} else {
			ret = mcp_smbus_write(mcp, addr, command, &data->byte,
						1, MCP2221_I2C_WR_DATA, 1);
		}
		break;
	case I2C_SMBUS_WORD_DATA:
		if (read_write == I2C_SMBUS_READ) {
			ret = mcp_smbus_write(mcp, addr, command, NULL,
						0, MCP2221_I2C_WR_NO_STOP, 0);
			if (ret)
				goto exit;

			ret = mcp_i2c_smbus_read(mcp, NULL,
						MCP2221_I2C_RD_RPT_START,
						addr, 2, (u8 *)&data->word);
		} else {
			ret = mcp_smbus_write(mcp, addr, command,
						(u8 *)&data->word, 2,
						MCP2221_I2C_WR_DATA, 1);
		}
		break;
	case I2C_SMBUS_BLOCK_DATA:
		if (read_write == I2C_SMBUS_READ) {
			ret = mcp_smbus_write(mcp, addr, command, NULL,
						0, MCP2221_I2C_WR_NO_STOP, 1);
			if (ret)
				goto exit;

			mcp->rxbuf_idx = 0;
			mcp->rxbuf = data->block;
			mcp->txbuf[0] = MCP2221_I2C_GET_DATA;
			ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
			if (ret)
				goto exit;
		} else {
			if (!data->block[0]) {
				ret = -EINVAL;
				goto exit;
			}
			ret = mcp_smbus_write(mcp, addr, command, data->block,
						data->block[0] + 1,
						MCP2221_I2C_WR_DATA, 1);
		}
		break;
	case I2C_SMBUS_I2C_BLOCK_DATA:
		if (read_write == I2C_SMBUS_READ) {
			ret = mcp_smbus_write(mcp, addr, command, NULL,
						0, MCP2221_I2C_WR_NO_STOP, 1);
			if (ret)
				goto exit;

			mcp->rxbuf_idx = 0;
			mcp->rxbuf = data->block;
			mcp->txbuf[0] = MCP2221_I2C_GET_DATA;
			ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
			if (ret)
				goto exit;
		} else {
			if (!data->block[0]) {
				ret = -EINVAL;
				goto exit;
			}
			ret = mcp_smbus_write(mcp, addr, command,
						&data->block[1], data->block[0],
						MCP2221_I2C_WR_DATA, 1);
		}
		break;
	case I2C_SMBUS_PROC_CALL:
		ret = mcp_smbus_write(mcp, addr, command,
						(u8 *)&data->word,
						2, MCP2221_I2C_WR_NO_STOP, 0);
		if (ret)
			goto exit;

		ret = mcp_i2c_smbus_read(mcp, NULL,
						MCP2221_I2C_RD_RPT_START,
						addr, 2, (u8 *)&data->word);
		break;
	case I2C_SMBUS_BLOCK_PROC_CALL:
		ret = mcp_smbus_write(mcp, addr, command, data->block,
						data->block[0] + 1,
						MCP2221_I2C_WR_NO_STOP, 0);
		if (ret)
			goto exit;

		ret = mcp_i2c_smbus_read(mcp, NULL,
						MCP2221_I2C_RD_RPT_START,
						addr, I2C_SMBUS_BLOCK_MAX,
						data->block);
		break;
	default:
		dev_err(&mcp->adapter.dev,
			"unsupported smbus transaction size:%d\n", size);
		ret = -EOPNOTSUPP;
	}

exit:
	hid_hw_power(mcp->hdev, PM_HINT_NORMAL);
	mutex_unlock(&mcp->lock);
	return ret;
}

static u32 mcp_i2c_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_I2C |
			I2C_FUNC_SMBUS_READ_BLOCK_DATA |
			I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
			(I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_PEC);
}

static const struct i2c_algorithm mcp_i2c_algo = {
	.master_xfer = mcp_i2c_xfer,
	.smbus_xfer = mcp_smbus_xfer,
	.functionality = mcp_i2c_func,
};

static int mcp_gpio_get(struct gpio_chip *gc,
				unsigned int offset)
{
	int ret;
	struct mcp2221 *mcp = gpiochip_get_data(gc);

	mcp->txbuf[0] = MCP2221_GPIO_GET;

	mcp->gp_idx = offsetof(struct mcp_get_gpio, gpio[offset].value);

	mutex_lock(&mcp->lock);
	ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
	mutex_unlock(&mcp->lock);

	return ret;
}

static void mcp_gpio_set(struct gpio_chip *gc,
				unsigned int offset, int value)
{
	struct mcp2221 *mcp = gpiochip_get_data(gc);

	memset(mcp->txbuf, 0, 18);
	mcp->txbuf[0] = MCP2221_GPIO_SET;

	mcp->gp_idx = offsetof(struct mcp_set_gpio, gpio[offset].value);

	mcp->txbuf[mcp->gp_idx - 1] = 1;
	mcp->txbuf[mcp->gp_idx] = !!value;

	mutex_lock(&mcp->lock);
	mcp_send_data_req_status(mcp, mcp->txbuf, 18);
	mutex_unlock(&mcp->lock);
}

static int mcp_gpio_dir_set(struct mcp2221 *mcp,
				unsigned int offset, u8 val)
{
	memset(mcp->txbuf, 0, 18);
	mcp->txbuf[0] = MCP2221_GPIO_SET;

	mcp->gp_idx = offsetof(struct mcp_set_gpio, gpio[offset].direction);

	mcp->txbuf[mcp->gp_idx - 1] = 1;
	mcp->txbuf[mcp->gp_idx] = val;

	return mcp_send_data_req_status(mcp, mcp->txbuf, 18);
}

static int mcp_gpio_direction_input(struct gpio_chip *gc,
				unsigned int offset)
{
	int ret;
	struct mcp2221 *mcp = gpiochip_get_data(gc);

	mutex_lock(&mcp->lock);
	ret = mcp_gpio_dir_set(mcp, offset, MCP2221_DIR_IN);
	mutex_unlock(&mcp->lock);

	return ret;
}

static int mcp_gpio_direction_output(struct gpio_chip *gc,
				unsigned int offset, int value)
{
	int ret;
	struct mcp2221 *mcp = gpiochip_get_data(gc);

	mutex_lock(&mcp->lock);
	ret = mcp_gpio_dir_set(mcp, offset, MCP2221_DIR_OUT);
	mutex_unlock(&mcp->lock);

	/* Can't configure as output, bailout early */
	if (ret)
		return ret;

	mcp_gpio_set(gc, offset, value);

	return 0;
}

static int mcp_gpio_get_direction(struct gpio_chip *gc,
				unsigned int offset)
{
	int ret;
	struct mcp2221 *mcp = gpiochip_get_data(gc);

	mcp->txbuf[0] = MCP2221_GPIO_GET;

	mcp->gp_idx = offsetof(struct mcp_get_gpio, gpio[offset].direction);

	mutex_lock(&mcp->lock);
	ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1);
	mutex_unlock(&mcp->lock);

	if (ret)
		return ret;

	if (mcp->gpio_dir == MCP2221_DIR_IN)
		return GPIO_LINE_DIRECTION_IN;

	return GPIO_LINE_DIRECTION_OUT;
}

/* Gives current state of i2c engine inside mcp2221 */
static int mcp_get_i2c_eng_state(struct mcp2221 *mcp,
				u8 *data, u8 idx)
{
	int ret;

	switch (data[idx]) {
	case MCP2221_I2C_WRADDRL_NACK:
	case MCP2221_I2C_WRADDRL_SEND:
		ret = -ENXIO;
		break;
	case MCP2221_I2C_START_TOUT:
	case MCP2221_I2C_STOP_TOUT:
	case MCP2221_I2C_WRADDRL_TOUT:
	case MCP2221_I2C_WRDATA_TOUT:
		ret = -ETIMEDOUT;
		break;
	case MCP2221_I2C_ENG_BUSY:
		ret = -EAGAIN;
		break;
	case MCP2221_SUCCESS:
		ret = 0x00;
		break;
	default:
		ret = -EIO;
	}

	return ret;
}

/*
 * MCP2221 uses interrupt endpoint for input reports. This function
 * is called by HID layer when it receives i/p report from mcp2221,
 * which is actually a response to the previously sent command.
 *
 * MCP2221A firmware specific return codes are parsed and 0 or
 * appropriate negative error code is returned. Delayed response
 * results in timeout error and stray reponses results in -EIO.
 */
static int mcp2221_raw_event(struct hid_device *hdev,
				struct hid_report *report, u8 *data, int size)
{
	u8 *buf;
	struct mcp2221 *mcp = hid_get_drvdata(hdev);

	switch (data[0]) {

	case MCP2221_I2C_WR_DATA:
	case MCP2221_I2C_WR_NO_STOP:
	case MCP2221_I2C_RD_DATA:
	case MCP2221_I2C_RD_RPT_START:
		switch (data[1]) {
		case MCP2221_SUCCESS:
			mcp->status = 0;
			break;
		default:
			mcp->status = mcp_get_i2c_eng_state(mcp, data, 2);
		}
		complete(&mcp->wait_in_report);
		break;

	case MCP2221_I2C_PARAM_OR_STATUS:
		switch (data[1]) {
		case MCP2221_SUCCESS:
			if ((mcp->txbuf[3] == MCP2221_I2C_SET_SPEED) &&
				(data[3] != MCP2221_I2C_SET_SPEED)) {
				mcp->status = -EAGAIN;
				break;
			}
			if (data[20] & MCP2221_I2C_MASK_ADDR_NACK) {
				mcp->status = -ENXIO;
				break;
			}
			mcp->status = mcp_get_i2c_eng_state(mcp, data, 8);
			break;
		default:
			mcp->status = -EIO;
		}
		complete(&mcp->wait_in_report);
		break;

	case MCP2221_I2C_GET_DATA:
		switch (data[1]) {
		case MCP2221_SUCCESS:
			if (data[2] == MCP2221_I2C_ADDR_NACK) {
				mcp->status = -ENXIO;
				break;
			}
			if (!mcp_get_i2c_eng_state(mcp, data, 2)
				&& (data[3] == 0)) {
				mcp->status = 0;
				break;
			}
			if (data[3] == 127) {
				mcp->status = -EIO;
				break;
			}
			if (data[2] == MCP2221_I2C_READ_COMPL) {
				buf = mcp->rxbuf;
				memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]);
				mcp->rxbuf_idx = mcp->rxbuf_idx + data[3];
				mcp->status = 0;
				break;
			}
			mcp->status = -EIO;
			break;
		default:
			mcp->status = -EIO;
		}
		complete(&mcp->wait_in_report);
		break;

	case MCP2221_GPIO_GET:
		switch (data[1]) {
		case MCP2221_SUCCESS:
			if ((data[mcp->gp_idx] == MCP2221_ALT_F_NOT_GPIOV) ||
				(data[mcp->gp_idx + 1] == MCP2221_ALT_F_NOT_GPIOD)) {
				mcp->status = -ENOENT;
			} else {
				mcp->status = !!data[mcp->gp_idx];
				mcp->gpio_dir = data[mcp->gp_idx + 1];
			}
			break;
		default:
			mcp->status = -EAGAIN;
		}
		complete(&mcp->wait_in_report);
		break;

	case MCP2221_GPIO_SET:
		switch (data[1]) {
		case MCP2221_SUCCESS:
			if ((data[mcp->gp_idx] == MCP2221_ALT_F_NOT_GPIOV) ||
				(data[mcp->gp_idx - 1] == MCP2221_ALT_F_NOT_GPIOV)) {
				mcp->status = -ENOENT;
			} else {
				mcp->status = 0;
			}
			break;
		default:
			mcp->status = -EAGAIN;
		}
		complete(&mcp->wait_in_report);
		break;

	default:
		mcp->status = -EIO;
		complete(&mcp->wait_in_report);
	}

	return 1;
}

static int mcp2221_probe(struct hid_device *hdev,
					const struct hid_device_id *id)
{
	int ret;
	struct mcp2221 *mcp;

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

	ret = hid_parse(hdev);
	if (ret) {
		hid_err(hdev, "can't parse reports\n");
		return ret;
	}

	ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
	if (ret) {
		hid_err(hdev, "can't start hardware\n");
		return ret;
	}

	ret = hid_hw_open(hdev);
	if (ret) {
		hid_err(hdev, "can't open device\n");
		goto err_hstop;
	}

	mutex_init(&mcp->lock);
	init_completion(&mcp->wait_in_report);
	hid_set_drvdata(hdev, mcp);
	mcp->hdev = hdev;

	/* Set I2C bus clock diviser */
	if (i2c_clk_freq > 400)
		i2c_clk_freq = 400;
	if (i2c_clk_freq < 50)
		i2c_clk_freq = 50;
	mcp->cur_i2c_clk_div = (12000000 / (i2c_clk_freq * 1000)) - 3;

	mcp->adapter.owner = THIS_MODULE;
	mcp->adapter.class = I2C_CLASS_HWMON;
	mcp->adapter.algo = &mcp_i2c_algo;
	mcp->adapter.retries = 1;
	mcp->adapter.dev.parent = &hdev->dev;
	snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),
			"MCP2221 usb-i2c bridge on hidraw%d",
			((struct hidraw *)hdev->hidraw)->minor);

	ret = i2c_add_adapter(&mcp->adapter);
	if (ret) {
		hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret);
		goto err_i2c;
	}
	i2c_set_adapdata(&mcp->adapter, mcp);

	/* Setup GPIO chip */
	mcp->gc = devm_kzalloc(&hdev->dev, sizeof(*mcp->gc), GFP_KERNEL);
	if (!mcp->gc) {
		ret = -ENOMEM;
		goto err_gc;
	}

	mcp->gc->label = "mcp2221_gpio";
	mcp->gc->direction_input = mcp_gpio_direction_input;
	mcp->gc->direction_output = mcp_gpio_direction_output;
	mcp->gc->get_direction = mcp_gpio_get_direction;
	mcp->gc->set = mcp_gpio_set;
	mcp->gc->get = mcp_gpio_get;
	mcp->gc->ngpio = MCP_NGPIO;
	mcp->gc->base = -1;
	mcp->gc->can_sleep = 1;
	mcp->gc->parent = &hdev->dev;

	ret = devm_gpiochip_add_data(&hdev->dev, mcp->gc, mcp);
	if (ret)
		goto err_gc;

	return 0;

err_gc:
	i2c_del_adapter(&mcp->adapter);
err_i2c:
	hid_hw_close(mcp->hdev);
err_hstop:
	hid_hw_stop(mcp->hdev);
	return ret;
}

static void mcp2221_remove(struct hid_device *hdev)
{
	struct mcp2221 *mcp = hid_get_drvdata(hdev);

	i2c_del_adapter(&mcp->adapter);
	hid_hw_close(mcp->hdev);
	hid_hw_stop(mcp->hdev);
}

static const struct hid_device_id mcp2221_devices[] = {
	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_MCP2221) },
	{ }
};
MODULE_DEVICE_TABLE(hid, mcp2221_devices);

static struct hid_driver mcp2221_driver = {
	.name		= "mcp2221",
	.id_table	= mcp2221_devices,
	.probe		= mcp2221_probe,
	.remove		= mcp2221_remove,
	.raw_event	= mcp2221_raw_event,
};

/* Register with HID core */
module_hid_driver(mcp2221_driver);

MODULE_AUTHOR("Rishi Gupta <gupt21@gmail.com>");
MODULE_DESCRIPTION("MCP2221 Microchip HID USB to I2C master bridge");
MODULE_LICENSE("GPL v2");
