/*
 * ICUSB - for MUSB Host Driver
 *
 * Copyright 2015 Mediatek Inc.
 *	Marvin Lin <marvin.lin@mediatek.com>
 *	Arvin Wang <arvin.wang@mediatek.com>
 *	Vincent Fan <vincent.fan@mediatek.com>
 *	Bryant Lu <bryant.lu@mediatek.com>
 *	Yu-Chang Wang <yu-chang.wang@mediatek.com>
 *	Macpaul Lin <macpaul.lin@mediatek.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/hid.h>

#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <linux/skbuff.h>

/*
 * Version Information
 */
#define DRIVER_VERSION ""
#define DRIVER_AUTHOR ""
#define DRIVER_DESC "USB ICUSB DRIVER"
#define DRIVER_LICENSE "GPL"

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE(DRIVER_LICENSE);

#define ICCD_INTERFACE_CLASS 0x0B
#define ICCD_CLASS_DESCRIPTOR_LENGTH	(0x36)

#include "usb.h"
#include "musbfsh_icusb.h"

struct usb_icusb {
	char name[128];
};

struct my_attr power_resume_time_neogo_attr = {
	.attr.name = "power_resume_time_neogo",
	.attr.mode = 0644,
#ifdef MTK_ICUSB_POWER_AND_RESUME_TIME_NEOGO_SUPPORT
	.value = 1
#else
	.value = 0
#endif
};

static struct my_attr my_attr_test = {
	.attr.name = "my_attr_test",
	.attr.mode = 0644,
	.value = 1
};

static struct attribute *myattr[] = {
	(struct attribute *)&my_attr_test,
	(struct attribute *)&power_resume_time_neogo_attr,
	(struct attribute *)&skip_session_req_attr,
	(struct attribute *)&skip_enable_session_attr,
	(struct attribute *)&skip_mac_init_attr,
	(struct attribute *)&resistor_control_attr,
	(struct attribute *)&hw_dbg_attr,
	(struct attribute *)&skip_port_pm_attr,
	NULL
};

static struct IC_USB_CMD ic_cmd;
unsigned int g_ic_usb_status =
	((USB_PORT1_DISCONNECT_DONE) << USB_PORT1_STS_SHIFT);
static struct sock *netlink_sock;
static u_int g_pid;
static struct proc_dir_entry *proc_drv_icusb_dir_entry;

static void icusb_dump_data(char *buf, int len);
static void set_icusb_phy_power_negotiation_fail(void);
static void set_icusb_phy_power_negotiation_ok(void);
static void set_icusb_data_of_interface_power_request(short data);

static void icusb_resume_time_negotiation(struct usb_device *dev)
{
	int ret;
	int retries = IC_USB_RETRIES_RESUME_TIME_NEGOTIATION;
	char resume_time_negotiation_data[IC_USB_LEN_RESUME_TIME_NEGOTIATION];

	while (retries-- > 0) {
		MYDBG("");
		ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
				      IC_USB_REQ_GET_INTERFACE_RESUME_TIME,
				      IC_USB_REQ_TYPE_GET_INTERFACE_RESUME_TIME,
				      IC_USB_WVALUE_RESUME_TIME_NEGOTIATION,
				      IC_USB_WINDEX_RESUME_TIME_NEGOTIATION,
				      resume_time_negotiation_data,
				      IC_USB_LEN_RESUME_TIME_NEGOTIATION,
				      USB_CTRL_GET_TIMEOUT);
		if (ret < 0) {
			MYDBG("ret : %d\n", ret);
			continue;
		} else {
			MYDBG("");
			icusb_dump_data(resume_time_negotiation_data,
					IC_USB_LEN_RESUME_TIME_NEGOTIATION);
			break;
		}

	}
}

void icusb_power_negotiation(struct usb_device *dev)
{
	int ret;
	int retries = IC_USB_RETRIES_POWER_NEGOTIATION;
	char get_power_negotiation_data[IC_USB_LEN_POWER_NEGOTIATION];
	char set_power_negotiation_data[IC_USB_LEN_POWER_NEGOTIATION];
	int power_negotiation_done = 0;
	enum PHY_VOLTAGE_TYPE phy_volt;

	while (retries-- > 0) {
		MYDBG("");
		power_negotiation_done = 0;
		ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
				      IC_USB_REQ_GET_IFACE_POWER,
				      IC_USB_REQ_TYPE_GET_IFACE_POWER,
				      IC_USB_WVALUE_POWER_NEGOTIATION,
				      IC_USB_WINDEX_POWER_NEGOTIATION,
				      get_power_negotiation_data,
				      IC_USB_LEN_POWER_NEGOTIATION,
				      USB_CTRL_GET_TIMEOUT);
		if (ret < 0) {
			MYDBG("ret : %d\n", ret);
			continue;
		} else {
			MYDBG("");
			icusb_dump_data(get_power_negotiation_data,
					IC_USB_LEN_POWER_NEGOTIATION);

			/* copy the prefer bit from get interface power */
			set_power_negotiation_data[0] =
				(get_power_negotiation_data[0] &
					IC_USB_PREFER_CLASSB_ENABLE_BIT);

			/* set our current voltage */
			phy_volt = get_usb11_phy_voltage();
			if (phy_volt == VOL_33)
				set_power_negotiation_data[0] |=
					(char)IC_USB_CLASSB;
			else if (phy_volt == VOL_18)
				set_power_negotiation_data[0] |=
					(char)IC_USB_CLASSC;
			else
				MYDBG("");

			/* set current */
			if (set_power_negotiation_data[1] > IC_USB_CURRENT) {
				MYDBG("");
				set_power_negotiation_data[1] = IC_USB_CURRENT;
			} else {
				MYDBG("");
				set_power_negotiation_data[1] =
					get_power_negotiation_data[1];
			}
			MYDBG("power_negotiation_data[0] : 0x%x",
			      set_power_negotiation_data[0]);
			MYDBG("power_negotiation_data[1] : 0x%x",
			     set_power_negotiation_data[1]);
			MYDBG("IC_USB_CURRENT :%d\n", IC_USB_CURRENT);

			ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
					      IC_USB_REQ_SET_IFACE_POWER,
					      IC_USB_REQ_TYPE_SET_IFACE_POWER,
					      IC_USB_WVALUE_POWER_NEGOTIATION,
					      IC_USB_WINDEX_POWER_NEGOTIATION,
					      set_power_negotiation_data,
					      IC_USB_LEN_POWER_NEGOTIATION,
					      USB_CTRL_SET_TIMEOUT);

			if (ret < 0) {
				MYDBG("ret : %d\n", ret);
			} else {
				MYDBG("");
				power_negotiation_done = 1;
				break;
			}
			/* break; */
		}
	}

	MYDBG("retries : %d\n", retries);
	if (!power_negotiation_done) {
		set_icusb_phy_power_negotiation_fail();
	} else {
		set_icusb_data_of_interface_power_request(
			*((short *)get_power_negotiation_data));
		set_icusb_phy_power_negotiation_ok();
	}
}

void usb11_wait_disconnect_done(int value)
{
	if (is_usb11_enabled()) {
		while (1) {
			unsigned int ic_usb_status = g_ic_usb_status;

			MYDBG("ic_usb_status : %x\n", ic_usb_status);
			ic_usb_status &=
				(USB_PORT1_STS_MSK << USB_PORT1_STS_SHIFT);
			MYDBG("ic_usb_status : %x\n", ic_usb_status);

			if (ic_usb_status ==
				(USB_PORT1_DISCONNECT_DONE <<
					USB_PORT1_STS_SHIFT)) {
				MYDBG("USB_PORT1_DISCONNECT_DONE\n");
				break;
			}

			if (ic_usb_status ==
				(USB_PORT1_DISCONNECTING <<
					USB_PORT1_STS_SHIFT))
				MYDBG("USB_PORT1_DISCONNECTING\n");

			mdelay(10);
		}
	} else {
		MYDBG("usb11 is not enabled, skip\n");
		MYDBG("usb11_wait_disconnect_done()\n");
	}

}

int check_usb11_sts_disconnect_done(void)
{
	unsigned int ic_usb_status = g_ic_usb_status;

	MYDBG("ic_usb_status : %x\n", ic_usb_status);
	ic_usb_status &= (USB_PORT1_STS_MSK << USB_PORT1_STS_SHIFT);
	MYDBG("ic_usb_status : %x\n", ic_usb_status);

	if (ic_usb_status ==
	    (USB_PORT1_DISCONNECT_DONE << USB_PORT1_STS_SHIFT)) {
		MYDBG("USB_PORT1_DISCONNECT_DONE got\n");
		return 1;
	} else {
		return 0;
	}

}

void set_usb11_sts_connect(void)
{
	MYDBG("...................");
	g_ic_usb_status &= ~(USB_PORT1_STS_MSK << USB_PORT1_STS_SHIFT);
	g_ic_usb_status |= ((USB_PORT1_CONNECT) << USB_PORT1_STS_SHIFT);
}

void set_usb11_sts_disconnecting(void)
{
	MYDBG("...................");
	g_ic_usb_status &= ~(USB_PORT1_STS_MSK << USB_PORT1_STS_SHIFT);
	g_ic_usb_status |= ((USB_PORT1_DISCONNECTING) << USB_PORT1_STS_SHIFT);
}

void set_icusb_sts_disconnect_done(void)
{
	MYDBG("...................");
	g_ic_usb_status &= ~(USB_PORT1_STS_MSK << USB_PORT1_STS_SHIFT);
	g_ic_usb_status |= ((USB_PORT1_DISCONNECT_DONE) << USB_PORT1_STS_SHIFT);
}

void set_icusb_data_of_interface_power_request(short data)
{
	MYDBG("...................");
	g_ic_usb_status |= ((data) << PREFER_VOL_CLASS_SHIFT);
}

void reset_usb11_phy_power_negotiation_status(void)
{
	MYDBG("...................");

	g_ic_usb_status &= ~(PREFER_VOL_STS_MSK << PREFER_VOL_STS_SHIFT);
	g_ic_usb_status |= ((PREFER_VOL_NOT_INITED) << PREFER_VOL_STS_SHIFT);

}

void set_icusb_phy_power_negotiation_fail(void)
{
	MYDBG("...................");

	g_ic_usb_status &= ~(PREFER_VOL_STS_MSK << PREFER_VOL_STS_SHIFT);
	g_ic_usb_status |= ((PREFER_VOL_PWR_NEG_FAIL) << PREFER_VOL_STS_SHIFT);

}

void set_icusb_phy_power_negotiation_ok(void)
{
	MYDBG("...................");

	g_ic_usb_status &= ~(PREFER_VOL_STS_MSK << PREFER_VOL_STS_SHIFT);
	g_ic_usb_status |= ((PREFER_VOL_PWR_NEG_OK) << PREFER_VOL_STS_SHIFT);

}


void usb11_phy_prefer_3v_status_check(void)
{
	unsigned int ic_usb_status = g_ic_usb_status;

	MYDBG("ic_usb_status : %x\n", ic_usb_status);
	ic_usb_status &= (PREFER_VOL_STS_MSK << PREFER_VOL_STS_SHIFT);
	MYDBG("ic_usb_status : %x\n", ic_usb_status);
}


void icusb_dump_data(char *buf, int len)
{
	int i;

	for (i = 0; i < len; i++)
		MYDBG("data[%d]: %x\n", i, buf[i]);

}

int usb11_init_phy_by_voltage(enum PHY_VOLTAGE_TYPE phy_volt)
{
	musbfsh_init_phy_by_voltage(phy_volt);
	return 0;
}

int usb11_session_control(enum SESSION_CONTROL_ACTION action)
{
	if (action == START_SESSION)
		musbfsh_start_session();
	else if (action == STOP_SESSION) {
		/* musbfsh_stop_session(); */
		if (!is_usb11_enabled()) {
			mt65xx_usb11_mac_reset_and_phy_stress_set();
		} else {
			MYDBG("usb11 has been enabled, skip");
			MYDBG("mt65xx_usb11_mac_reset_and_phy_stress_set()\n");
		}
	} else
		MYDBG("unknown action\n");


	return 0;
}

static void udp_reply(int pid, int seq, void *payload)
{
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	int size = strlen(payload) + 1;
	int len = NLMSG_SPACE(size);
	void *data;
	int ret;

	skb = alloc_skb(len, GFP_ATOMIC);
	if (!skb)
		return;
	/* 3.10 specific */
	nlh = __nlmsg_put(skb, pid, seq, 0, size, 0);
	nlh->nlmsg_flags = 0;
	data = NLMSG_DATA(nlh);
	memcpy(data, payload, size);

	/* 3.10 specific */
	NETLINK_CB(skb).portid = 0;	/* from kernel */
	NETLINK_CB(skb).dst_group = 0;	/* unicast */
	ret = netlink_unicast(netlink_sock, skb, pid, MSG_DONTWAIT);
	if (ret < 0)
		MYDBG("send failed\n");
}

/* Receive messages from netlink socket. */
static void udp_receive(struct sk_buff *skb)
{
	kuid_t uid,
	u_int seq;
	void *data;
	struct nlmsghdr *nlh;
	char reply_data[16];

	MYDBG("");
	nlh = (struct nlmsghdr *)skb->data;

	/* global here */
	g_pid = NETLINK_CREDS(skb)->pid;
	uid = NETLINK_CREDS(skb)->uid;
	seq = nlh->nlmsg_seq;
	data = NLMSG_DATA(nlh);
	MYDBG("recv skb from user space pid:%d seq:%d\n",
	      g_pid, seq);
	MYDBG("data is :%s\n", (char *)data);


	sprintf(reply_data, "%d", g_pid);
	udp_reply(g_pid, 0, reply_data);
}

struct netlink_kernel_cfg nl_cfg = {
	.input = udp_receive,
};


static ssize_t default_show(struct kobject *kobj, struct attribute *attr,
			    char *buf)
{
	struct my_attr *a = container_of(attr, struct my_attr, attr);

	return scnprintf(buf, PAGE_SIZE, "%d\n", a->value);
}

static ssize_t default_store(struct kobject *kobj, struct attribute *attr,
			     const char *buf, size_t len)
{
	struct my_attr *a = container_of(attr, struct my_attr, attr);
	int result = kstrtoul(buf, 0, (unsigned long *)&a->value);

	if (result)
		return sizeof(int);
	else
		return -EINVAL;
}

static const struct sysfs_ops myops = {
	.show = default_show,
	.store = default_store,
};

static struct kobj_type mytype = {
	.sysfs_ops = &myops,
	.default_attrs = myattr,
};

struct kobject *mykobj;
void create_icusb_sysfs_attr(void)
{
	int err = -1;

	mykobj = kzalloc(sizeof(*mykobj), GFP_KERNEL);
	if (mykobj) {
		MYDBG("");
		kobject_init(mykobj, &mytype);
		if (kobject_add(mykobj, NULL, "%s", "icusb_attr")) {
			err = -1;
			MYDBG("Sysfs creation failed\n");
			kobject_put(mykobj);
			mykobj = NULL;
		}
		err = 0;
	}
	return;

}

static ssize_t musbfsh_ic_tmp_proc_entry(struct file *file_ptr,
					 const char __user *user_buffer,
					 size_t count, loff_t *position)
{
	char cmd[64];
	int ret = copy_from_user((char *)&cmd, user_buffer, count);

	if (ret != 0)
		return -EFAULT;

	if (cmd[0] == '4') {
		MYDBG("");
		udp_reply(g_pid, 0, "HELLO, SS7_IC_USB!!!");
	}

	MYDBG("");

	return count;
}

const struct file_operations musbfsh_ic_tmp_proc_fops = {
	.write = musbfsh_ic_tmp_proc_entry
};

void create_ic_tmp_entry(void)
{
	struct proc_dir_entry *pr_entry;

	if (proc_drv_icusb_dir_entry == NULL) {
		MYDBG("[%s]: /proc/driver/icusb not exist\n", __func__);
		return;
	}

	pr_entry =
		proc_create("IC_TMP_ENTRY", 0660, proc_drv_icusb_dir_entry,
			&musbfsh_ic_tmp_proc_fops);
	if (pr_entry)
		MYDBG("add /proc/IC_TMP_ENTRY ok\n");
	else
		MYDBG("add /proc/IC_TMP_ENTRY fail\n");
}

static ssize_t musbfsh_ic_usb_cmd_proc_status_read(struct file *file_ptr,
						   char __user *user_buffer,
						   size_t count,
						   loff_t *position)
{
	int len;

	MYDBG("");

	if (copy_to_user(user_buffer,
			 &g_ic_usb_status, sizeof(g_ic_usb_status)) != 0)
		return -EFAULT;

	/* *position += count; */
	len = sizeof(g_ic_usb_status);
	return len;
}


ssize_t musbfsh_ic_usb_cmd_proc_entry(struct file *file_ptr,
				      const char __user *user_buffer,
				      size_t count, loff_t *position)
{


	int ret = copy_from_user((char *)&ic_cmd, user_buffer, count);

	if (ret != 0)
		return -EFAULT;

	MYDBG("type : %x, length : %x, data[0] : %x\n",
	      ic_cmd.type, ic_cmd.length, ic_cmd.data[0]);

	switch (ic_cmd.type) {
	case USB11_SESSION_CONTROL:
		MYDBG("");
		usb11_session_control(ic_cmd.data[0]);
		break;
	case USB11_INIT_PHY_BY_VOLTAGE:
		MYDBG("");
		usb11_init_phy_by_voltage(ic_cmd.data[0]);
		break;
	case USB11_WAIT_DISCONNECT_DONE:
		MYDBG("");
		usb11_wait_disconnect_done(ic_cmd.data[0]);
		break;
		/*--- special purpose ---*/
	case 's':
		MYDBG("create sysfs\n");
		create_icusb_sysfs_attr();
		break;
	case 't':
		MYDBG("create tmp proc\n");
		create_ic_tmp_entry();
		break;
	}
	return count;
}

static const struct file_operations musbfsh_ic_usb_cmd_proc_fops = {
	.read = musbfsh_ic_usb_cmd_proc_status_read,
	.write = musbfsh_ic_usb_cmd_proc_entry
};

void create_ic_usb_cmd_proc_entry(void)
{
	struct proc_dir_entry *prEntry;

	MYDBG("");
	proc_drv_icusb_dir_entry = proc_mkdir("driver/icusb", NULL);

	if (proc_drv_icusb_dir_entry == NULL) {
		MYDBG("[%s]: mkdir /proc/driver/icusb failed\n", __func__);
		return;
	}

	prEntry =
	    proc_create("IC_USB_CMD_ENTRY", 0660, proc_drv_icusb_dir_entry,
			&musbfsh_ic_usb_cmd_proc_fops);
	if (prEntry) {
		MYDBG("add IC_USB_CMD_ENTRY ok\n");
		netlink_sock = netlink_kernel_create(&init_net,
						     NETLINK_USERSOCK, &nl_cfg);
	} else {
		MYDBG("add IC_USB_CMD_ENTRY fail\n");
	}
}

void set_icusb_phy_power_negotiation(struct usb_device *udev)
{
	if (power_resume_time_neogo_attr.value) {
		icusb_power_negotiation(udev);
		icusb_resume_time_negotiation(udev);
	} else {
		set_icusb_phy_power_negotiation_ok();
	}
}
