/*
 * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/slab.h>
#include <linux/usb/cdc.h>

#include "gdm_mux.h"

static u16 packet_type[TTY_MAX_COUNT] = {0xF011, 0xF010};

#define USB_DEVICE_CDC_DATA(vid, pid) \
	.match_flags = \
		USB_DEVICE_ID_MATCH_DEVICE |\
		USB_DEVICE_ID_MATCH_INT_CLASS |\
		USB_DEVICE_ID_MATCH_INT_SUBCLASS,\
	.idVendor = vid,\
	.idProduct = pid,\
	.bInterfaceClass = USB_CLASS_COMM,\
	.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM

static const struct usb_device_id id_table[] = {
	{ USB_DEVICE_CDC_DATA(0x1076, 0x8000) }, /* GCT GDM7240 */
	{ USB_DEVICE_CDC_DATA(0x1076, 0x8f00) }, /* GCT GDM7243 */
	{ USB_DEVICE_CDC_DATA(0x1076, 0x9000) }, /* GCT GDM7243 */
	{ USB_DEVICE_CDC_DATA(0x1d74, 0x2300) }, /* LGIT Phoenix */
	{}
};

MODULE_DEVICE_TABLE(usb, id_table);

static int packet_type_to_index(u16 packetType)
{
	int i;

	for (i = 0; i < TTY_MAX_COUNT; i++) {
		if (packet_type[i] == packetType)
			return i;
	}

	return -1;
}

static struct mux_tx *alloc_mux_tx(int len)
{
	struct mux_tx *t;

	t = kzalloc(sizeof(*t), GFP_ATOMIC);
	if (!t)
		return NULL;

	t->urb = usb_alloc_urb(0, GFP_ATOMIC);
	t->buf = kmalloc(MUX_TX_MAX_SIZE, GFP_ATOMIC);
	if (!t->urb || !t->buf) {
		usb_free_urb(t->urb);
		kfree(t->buf);
		kfree(t);
		return NULL;
	}

	return t;
}

static void free_mux_tx(struct mux_tx *t)
{
	if (t) {
		usb_free_urb(t->urb);
		kfree(t->buf);
		kfree(t);
	}
}

static struct mux_rx *alloc_mux_rx(void)
{
	struct mux_rx *r;

	r = kzalloc(sizeof(*r), GFP_KERNEL);
	if (!r)
		return NULL;

	r->urb = usb_alloc_urb(0, GFP_KERNEL);
	r->buf = kmalloc(MUX_RX_MAX_SIZE, GFP_KERNEL);
	if (!r->urb || !r->buf) {
		usb_free_urb(r->urb);
		kfree(r->buf);
		kfree(r);
		return NULL;
	}

	return r;
}

static void free_mux_rx(struct mux_rx *r)
{
	if (r) {
		usb_free_urb(r->urb);
		kfree(r->buf);
		kfree(r);
	}
}

static struct mux_rx *get_rx_struct(struct rx_cxt *rx)
{
	struct mux_rx *r;
	unsigned long flags;

	spin_lock_irqsave(&rx->free_list_lock, flags);

	if (list_empty(&rx->rx_free_list)) {
		spin_unlock_irqrestore(&rx->free_list_lock, flags);
		return NULL;
	}

	r = list_entry(rx->rx_free_list.prev, struct mux_rx, free_list);
	list_del(&r->free_list);

	spin_unlock_irqrestore(&rx->free_list_lock, flags);

	return r;
}

static void put_rx_struct(struct rx_cxt *rx, struct mux_rx *r)
{
	unsigned long flags;

	spin_lock_irqsave(&rx->free_list_lock, flags);
	list_add_tail(&r->free_list, &rx->rx_free_list);
	spin_unlock_irqrestore(&rx->free_list_lock, flags);
}

static int up_to_host(struct mux_rx *r)
{
	struct mux_dev *mux_dev = r->mux_dev;
	struct mux_pkt_header *mux_header;
	unsigned int start_flag;
	unsigned int payload_size;
	unsigned short packet_type;
	int total_len;
	u32 packet_size_sum = r->offset;
	int index;
	int ret = TO_HOST_INVALID_PACKET;
	int len = r->len;

	while (1) {
		mux_header = (struct mux_pkt_header *)(r->buf +
						       packet_size_sum);
		start_flag = __le32_to_cpu(mux_header->start_flag);
		payload_size = __le32_to_cpu(mux_header->payload_size);
		packet_type = __le16_to_cpu(mux_header->packet_type);

		if (start_flag != START_FLAG) {
			pr_err("invalid START_FLAG %x\n", start_flag);
			break;
		}

		total_len = ALIGN(MUX_HEADER_SIZE + payload_size, 4);

		if (len - packet_size_sum <
			total_len) {
			pr_err("invalid payload : %d %d %04x\n",
			       payload_size, len, packet_type);
			break;
		}

		index = packet_type_to_index(packet_type);
		if (index < 0) {
			pr_err("invalid index %d\n", index);
			break;
		}

		ret = r->callback(mux_header->data,
				payload_size,
				index,
				mux_dev->tty_dev,
				RECV_PACKET_PROCESS_CONTINUE
				);
		if (ret == TO_HOST_BUFFER_REQUEST_FAIL) {
			r->offset += packet_size_sum;
			break;
		}

		packet_size_sum += total_len;
		if (len - packet_size_sum <= MUX_HEADER_SIZE + 2) {
			ret = r->callback(NULL,
					0,
					index,
					mux_dev->tty_dev,
					RECV_PACKET_PROCESS_COMPLETE
					);
			break;
		}
	}

	return ret;
}

static void do_rx(struct work_struct *work)
{
	struct mux_dev *mux_dev =
		container_of(work, struct mux_dev, work_rx.work);
	struct mux_rx *r;
	struct rx_cxt *rx = &mux_dev->rx;
	unsigned long flags;
	int ret = 0;

	while (1) {
		spin_lock_irqsave(&rx->to_host_lock, flags);
		if (list_empty(&rx->to_host_list)) {
			spin_unlock_irqrestore(&rx->to_host_lock, flags);
			break;
		}
		r = list_entry(rx->to_host_list.next, struct mux_rx,
			       to_host_list);
		list_del(&r->to_host_list);
		spin_unlock_irqrestore(&rx->to_host_lock, flags);

		ret = up_to_host(r);
		if (ret == TO_HOST_BUFFER_REQUEST_FAIL)
			pr_err("failed to send mux data to host\n");
		else
			put_rx_struct(rx, r);
	}
}

static void remove_rx_submit_list(struct mux_rx *r, struct rx_cxt *rx)
{
	unsigned long flags;
	struct mux_rx	*r_remove, *r_remove_next;

	spin_lock_irqsave(&rx->submit_list_lock, flags);
	list_for_each_entry_safe(r_remove, r_remove_next, &rx->rx_submit_list,
				 rx_submit_list) {
		if (r == r_remove)
			list_del(&r->rx_submit_list);
	}
	spin_unlock_irqrestore(&rx->submit_list_lock, flags);
}

static void gdm_mux_rcv_complete(struct urb *urb)
{
	struct mux_rx *r = urb->context;
	struct mux_dev *mux_dev = r->mux_dev;
	struct rx_cxt *rx = &mux_dev->rx;
	unsigned long flags;

	remove_rx_submit_list(r, rx);

	if (urb->status) {
		if (mux_dev->usb_state == PM_NORMAL)
			dev_err(&urb->dev->dev, "%s: urb status error %d\n",
				__func__, urb->status);
		put_rx_struct(rx, r);
	} else {
		r->len = r->urb->actual_length;
		spin_lock_irqsave(&rx->to_host_lock, flags);
		list_add_tail(&r->to_host_list, &rx->to_host_list);
		schedule_work(&mux_dev->work_rx.work);
		spin_unlock_irqrestore(&rx->to_host_lock, flags);
	}
}

static int gdm_mux_recv(void *priv_dev,
			int (*cb)(void *data, int len, int tty_index,
				  struct tty_dev *tty_dev, int complete))
{
	struct mux_dev *mux_dev = priv_dev;
	struct usb_device *usbdev = mux_dev->usbdev;
	struct mux_rx *r;
	struct rx_cxt *rx = &mux_dev->rx;
	unsigned long flags;
	int ret;

	if (!usbdev) {
		pr_err("device is disconnected\n");
		return -ENODEV;
	}

	r = get_rx_struct(rx);
	if (!r) {
		pr_err("get_rx_struct fail\n");
		return -ENOMEM;
	}

	r->offset = 0;
	r->mux_dev = (void *)mux_dev;
	r->callback = cb;
	mux_dev->rx_cb = cb;

	usb_fill_bulk_urb(r->urb,
			  usbdev,
			  usb_rcvbulkpipe(usbdev, 0x86),
			  r->buf,
			  MUX_RX_MAX_SIZE,
			  gdm_mux_rcv_complete,
			  r);

	spin_lock_irqsave(&rx->submit_list_lock, flags);
	list_add_tail(&r->rx_submit_list, &rx->rx_submit_list);
	spin_unlock_irqrestore(&rx->submit_list_lock, flags);

	ret = usb_submit_urb(r->urb, GFP_KERNEL);

	if (ret) {
		spin_lock_irqsave(&rx->submit_list_lock, flags);
		list_del(&r->rx_submit_list);
		spin_unlock_irqrestore(&rx->submit_list_lock, flags);

		put_rx_struct(rx, r);

		pr_err("usb_submit_urb ret=%d\n", ret);
	}

	usb_mark_last_busy(usbdev);

	return ret;
}

static void gdm_mux_send_complete(struct urb *urb)
{
	struct mux_tx *t = urb->context;

	if (urb->status == -ECONNRESET) {
		dev_info(&urb->dev->dev, "CONNRESET\n");
		free_mux_tx(t);
		return;
	}

	if (t->callback)
		t->callback(t->cb_data);

	free_mux_tx(t);
}

static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index,
			void (*cb)(void *data), void *cb_data)
{
	struct mux_dev *mux_dev = priv_dev;
	struct usb_device *usbdev = mux_dev->usbdev;
	struct mux_pkt_header *mux_header;
	struct mux_tx *t = NULL;
	static u32 seq_num = 1;
	int total_len;
	int ret;
	unsigned long flags;

	if (mux_dev->usb_state == PM_SUSPEND) {
		ret = usb_autopm_get_interface(mux_dev->intf);
		if (!ret)
			usb_autopm_put_interface(mux_dev->intf);
	}

	spin_lock_irqsave(&mux_dev->write_lock, flags);

	total_len = ALIGN(MUX_HEADER_SIZE + len, 4);

	t = alloc_mux_tx(total_len);
	if (!t) {
		pr_err("alloc_mux_tx fail\n");
		spin_unlock_irqrestore(&mux_dev->write_lock, flags);
		return -ENOMEM;
	}

	mux_header = (struct mux_pkt_header *)t->buf;
	mux_header->start_flag = __cpu_to_le32(START_FLAG);
	mux_header->seq_num = __cpu_to_le32(seq_num++);
	mux_header->payload_size = __cpu_to_le32((u32)len);
	mux_header->packet_type = __cpu_to_le16(packet_type[tty_index]);

	memcpy(t->buf + MUX_HEADER_SIZE, data, len);
	memset(t->buf + MUX_HEADER_SIZE + len, 0, total_len - MUX_HEADER_SIZE -
	       len);

	t->len = total_len;
	t->callback = cb;
	t->cb_data = cb_data;

	usb_fill_bulk_urb(t->urb,
			  usbdev,
			  usb_sndbulkpipe(usbdev, 5),
			  t->buf,
			  total_len,
			  gdm_mux_send_complete,
			  t);

	ret = usb_submit_urb(t->urb, GFP_ATOMIC);

	spin_unlock_irqrestore(&mux_dev->write_lock, flags);

	if (ret)
		pr_err("usb_submit_urb Error: %d\n", ret);

	usb_mark_last_busy(usbdev);

	return ret;
}

static int gdm_mux_send_control(void *priv_dev, int request, int value,
				void *buf, int len)
{
	struct mux_dev *mux_dev = priv_dev;
	struct usb_device *usbdev = mux_dev->usbdev;
	int ret;

	ret = usb_control_msg(usbdev,
			      usb_sndctrlpipe(usbdev, 0),
			      request,
			      USB_RT_ACM,
			      value,
			      2,
			      buf,
			      len,
			      5000
			     );

	if (ret < 0)
		pr_err("usb_control_msg error: %d\n", ret);

	return min(ret, 0);
}

static void release_usb(struct mux_dev *mux_dev)
{
	struct rx_cxt		*rx = &mux_dev->rx;
	struct mux_rx		*r, *r_next;
	unsigned long		flags;

	cancel_delayed_work(&mux_dev->work_rx);

	spin_lock_irqsave(&rx->submit_list_lock, flags);
	list_for_each_entry_safe(r, r_next, &rx->rx_submit_list,
				 rx_submit_list) {
		spin_unlock_irqrestore(&rx->submit_list_lock, flags);
		usb_kill_urb(r->urb);
		spin_lock_irqsave(&rx->submit_list_lock, flags);
	}
	spin_unlock_irqrestore(&rx->submit_list_lock, flags);

	spin_lock_irqsave(&rx->free_list_lock, flags);
	list_for_each_entry_safe(r, r_next, &rx->rx_free_list, free_list) {
		list_del(&r->free_list);
		free_mux_rx(r);
	}
	spin_unlock_irqrestore(&rx->free_list_lock, flags);

	spin_lock_irqsave(&rx->to_host_lock, flags);
	list_for_each_entry_safe(r, r_next, &rx->to_host_list, to_host_list) {
		if (r->mux_dev == (void *)mux_dev) {
			list_del(&r->to_host_list);
			free_mux_rx(r);
		}
	}
	spin_unlock_irqrestore(&rx->to_host_lock, flags);
}

static int init_usb(struct mux_dev *mux_dev)
{
	struct mux_rx *r;
	struct rx_cxt *rx = &mux_dev->rx;
	int ret = 0;
	int i;

	spin_lock_init(&mux_dev->write_lock);
	INIT_LIST_HEAD(&rx->to_host_list);
	INIT_LIST_HEAD(&rx->rx_submit_list);
	INIT_LIST_HEAD(&rx->rx_free_list);
	spin_lock_init(&rx->to_host_lock);
	spin_lock_init(&rx->submit_list_lock);
	spin_lock_init(&rx->free_list_lock);

	for (i = 0; i < MAX_ISSUE_NUM * 2; i++) {
		r = alloc_mux_rx();
		if (!r) {
			ret = -ENOMEM;
			break;
		}

		list_add(&r->free_list, &rx->rx_free_list);
	}

	INIT_DELAYED_WORK(&mux_dev->work_rx, do_rx);

	return ret;
}

static int gdm_mux_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
{
	struct mux_dev *mux_dev;
	struct tty_dev *tty_dev;
	u16 idVendor, idProduct;
	int bInterfaceNumber;
	int ret;
	int i;
	struct usb_device *usbdev = interface_to_usbdev(intf);

	bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;

	idVendor = __le16_to_cpu(usbdev->descriptor.idVendor);
	idProduct = __le16_to_cpu(usbdev->descriptor.idProduct);

	pr_info("mux vid = 0x%04x pid = 0x%04x\n", idVendor, idProduct);

	if (bInterfaceNumber != 2)
		return -ENODEV;

	mux_dev = kzalloc(sizeof(*mux_dev), GFP_KERNEL);
	if (!mux_dev)
		return -ENOMEM;

	tty_dev = kzalloc(sizeof(*tty_dev), GFP_KERNEL);
	if (!tty_dev) {
		ret = -ENOMEM;
		goto err_free_mux;
	}

	mux_dev->usbdev = usbdev;
	mux_dev->control_intf = intf;

	ret = init_usb(mux_dev);
	if (ret)
		goto err_free_usb;

	tty_dev->priv_dev = (void *)mux_dev;
	tty_dev->send_func = gdm_mux_send;
	tty_dev->recv_func = gdm_mux_recv;
	tty_dev->send_control = gdm_mux_send_control;

	ret = register_lte_tty_device(tty_dev, &intf->dev);
	if (ret)
		goto err_unregister_tty;

	for (i = 0; i < TTY_MAX_COUNT; i++)
		mux_dev->tty_dev = tty_dev;

	mux_dev->intf = intf;
	mux_dev->usb_state = PM_NORMAL;

	usb_get_dev(usbdev);
	usb_set_intfdata(intf, tty_dev);

	return 0;

err_unregister_tty:
	unregister_lte_tty_device(tty_dev);
err_free_usb:
	release_usb(mux_dev);
	kfree(tty_dev);
err_free_mux:
	kfree(mux_dev);

	return ret;
}

static void gdm_mux_disconnect(struct usb_interface *intf)
{
	struct tty_dev *tty_dev;
	struct mux_dev *mux_dev;
	struct usb_device *usbdev = interface_to_usbdev(intf);

	tty_dev = usb_get_intfdata(intf);

	mux_dev = tty_dev->priv_dev;

	release_usb(mux_dev);
	unregister_lte_tty_device(tty_dev);

	kfree(mux_dev);
	kfree(tty_dev);

	usb_put_dev(usbdev);
}

static int gdm_mux_suspend(struct usb_interface *intf, pm_message_t pm_msg)
{
	struct tty_dev *tty_dev;
	struct mux_dev *mux_dev;
	struct rx_cxt *rx;
	struct mux_rx *r, *r_next;
	unsigned long flags;

	tty_dev = usb_get_intfdata(intf);
	mux_dev = tty_dev->priv_dev;
	rx = &mux_dev->rx;

	cancel_work_sync(&mux_dev->work_rx.work);

	if (mux_dev->usb_state != PM_NORMAL) {
		dev_err(intf->usb_dev, "usb suspend - invalid state\n");
		return -1;
	}

	mux_dev->usb_state = PM_SUSPEND;

	spin_lock_irqsave(&rx->submit_list_lock, flags);
	list_for_each_entry_safe(r, r_next, &rx->rx_submit_list,
				 rx_submit_list) {
		spin_unlock_irqrestore(&rx->submit_list_lock, flags);
		usb_kill_urb(r->urb);
		spin_lock_irqsave(&rx->submit_list_lock, flags);
	}
	spin_unlock_irqrestore(&rx->submit_list_lock, flags);

	return 0;
}

static int gdm_mux_resume(struct usb_interface *intf)
{
	struct tty_dev *tty_dev;
	struct mux_dev *mux_dev;
	u8 i;

	tty_dev = usb_get_intfdata(intf);
	mux_dev = tty_dev->priv_dev;

	if (mux_dev->usb_state != PM_SUSPEND) {
		dev_err(intf->usb_dev, "usb resume - invalid state\n");
		return -1;
	}

	mux_dev->usb_state = PM_NORMAL;

	for (i = 0; i < MAX_ISSUE_NUM; i++)
		gdm_mux_recv(mux_dev, mux_dev->rx_cb);

	return 0;
}

static struct usb_driver gdm_mux_driver = {
	.name = "gdm_mux",
	.probe = gdm_mux_probe,
	.disconnect = gdm_mux_disconnect,
	.id_table = id_table,
	.supports_autosuspend = 1,
	.suspend = gdm_mux_suspend,
	.resume = gdm_mux_resume,
	.reset_resume = gdm_mux_resume,
};

static int __init gdm_usb_mux_init(void)
{
	register_lte_tty_driver();

	return usb_register(&gdm_mux_driver);
}

static void __exit gdm_usb_mux_exit(void)
{
	usb_deregister(&gdm_mux_driver);
	unregister_lte_tty_driver();
}

module_init(gdm_usb_mux_init);
module_exit(gdm_usb_mux_exit);

MODULE_DESCRIPTION("GCT LTE TTY Device Driver");
MODULE_LICENSE("GPL");
