/*
 * Infinity Unlimited USB Phoenix driver
 *
 * Copyright (C) 2010 James Courtier-Dutton (James@superbug.co.uk)

 * Copyright (C) 2007 Alain Degreffe (eczema@ecze.com)
 *
 * Original code taken from iuutool (Copyright (C) 2006 Juan Carlos BorrÃ¡s)
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *  And tested with help of WB Electronics
 *
 */
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include "iuu_phoenix.h"
#include <linux/random.h>

#define DRIVER_DESC "Infinity USB Unlimited Phoenix driver"

static const struct usb_device_id id_table[] = {
	{USB_DEVICE(IUU_USB_VENDOR_ID, IUU_USB_PRODUCT_ID)},
	{}			/* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);

/* turbo parameter */
static int boost = 100;
static int clockmode = 1;
static int cdmode = 1;
static int iuu_cardin;
static int iuu_cardout;
static bool xmas;
static int vcc_default = 5;

static int iuu_create_sysfs_attrs(struct usb_serial_port *port);
static int iuu_remove_sysfs_attrs(struct usb_serial_port *port);
static void read_rxcmd_callback(struct urb *urb);

struct iuu_private {
	spinlock_t lock;	/* store irq state */
	u8 line_status;
	int tiostatus;		/* store IUART SIGNAL for tiocmget call */
	u8 reset;		/* if 1 reset is needed */
	int poll;		/* number of poll */
	u8 *writebuf;		/* buffer for writing to device */
	int writelen;		/* num of byte to write to device */
	u8 *buf;		/* used for initialize speed */
	u8 len;
	int vcc;		/* vcc (either 3 or 5 V) */
	u32 baud;
	u32 boost;
	u32 clk;
};

static int iuu_port_probe(struct usb_serial_port *port)
{
	struct iuu_private *priv;
	int ret;

	priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->buf = kzalloc(256, GFP_KERNEL);
	if (!priv->buf) {
		kfree(priv);
		return -ENOMEM;
	}

	priv->writebuf = kzalloc(256, GFP_KERNEL);
	if (!priv->writebuf) {
		kfree(priv->buf);
		kfree(priv);
		return -ENOMEM;
	}

	priv->vcc = vcc_default;
	spin_lock_init(&priv->lock);

	usb_set_serial_port_data(port, priv);

	ret = iuu_create_sysfs_attrs(port);
	if (ret) {
		kfree(priv->writebuf);
		kfree(priv->buf);
		kfree(priv);
		return ret;
	}

	return 0;
}

static int iuu_port_remove(struct usb_serial_port *port)
{
	struct iuu_private *priv = usb_get_serial_port_data(port);

	iuu_remove_sysfs_attrs(port);
	kfree(priv->writebuf);
	kfree(priv->buf);
	kfree(priv);

	return 0;
}

static int iuu_tiocmset(struct tty_struct *tty,
			unsigned int set, unsigned int clear)
{
	struct usb_serial_port *port = tty->driver_data;
	struct iuu_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;

	/* FIXME: locking on tiomstatus */
	dev_dbg(&port->dev, "%s msg : SET = 0x%04x, CLEAR = 0x%04x\n",
		__func__, set, clear);

	spin_lock_irqsave(&priv->lock, flags);

	if ((set & TIOCM_RTS) && !(priv->tiostatus == TIOCM_RTS)) {
		dev_dbg(&port->dev, "%s TIOCMSET RESET called !!!\n", __func__);
		priv->reset = 1;
	}
	if (set & TIOCM_RTS)
		priv->tiostatus = TIOCM_RTS;

	spin_unlock_irqrestore(&priv->lock, flags);
	return 0;
}

/* This is used to provide a carrier detect mechanism
 * When a card is present, the response is 0x00
 * When no card , the reader respond with TIOCM_CD
 * This is known as CD autodetect mechanism
 */
static int iuu_tiocmget(struct tty_struct *tty)
{
	struct usb_serial_port *port = tty->driver_data;
	struct iuu_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	int rc;

	spin_lock_irqsave(&priv->lock, flags);
	rc = priv->tiostatus;
	spin_unlock_irqrestore(&priv->lock, flags);

	return rc;
}

static void iuu_rxcmd(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	int result;
	int status = urb->status;

	if (status) {
		dev_dbg(&port->dev, "%s - status = %d\n", __func__, status);
		/* error stop all */
		return;
	}


	memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1);
	usb_fill_bulk_urb(port->write_urb, port->serial->dev,
			  usb_sndbulkpipe(port->serial->dev,
					  port->bulk_out_endpointAddress),
			  port->write_urb->transfer_buffer, 1,
			  read_rxcmd_callback, port);
	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
}

static int iuu_reset(struct usb_serial_port *port, u8 wt)
{
	struct iuu_private *priv = usb_get_serial_port_data(port);
	int result;
	char *buf_ptr = port->write_urb->transfer_buffer;

	/* Prepare the reset sequence */

	*buf_ptr++ = IUU_RST_SET;
	*buf_ptr++ = IUU_DELAY_MS;
	*buf_ptr++ = wt;
	*buf_ptr = IUU_RST_CLEAR;

	/* send the sequence */

	usb_fill_bulk_urb(port->write_urb,
			  port->serial->dev,
			  usb_sndbulkpipe(port->serial->dev,
					  port->bulk_out_endpointAddress),
			  port->write_urb->transfer_buffer, 4, iuu_rxcmd, port);
	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
	priv->reset = 0;
	return result;
}

/* Status Function
 * Return value is
 * 0x00 = no card
 * 0x01 = smartcard
 * 0x02 = sim card
 */
static void iuu_update_status_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	struct iuu_private *priv = usb_get_serial_port_data(port);
	u8 *st;
	int status = urb->status;

	if (status) {
		dev_dbg(&port->dev, "%s - status = %d\n", __func__, status);
		/* error stop all */
		return;
	}

	st = urb->transfer_buffer;
	dev_dbg(&port->dev, "%s - enter\n", __func__);
	if (urb->actual_length == 1) {
		switch (st[0]) {
		case 0x1:
			priv->tiostatus = iuu_cardout;
			break;
		case 0x0:
			priv->tiostatus = iuu_cardin;
			break;
		default:
			priv->tiostatus = iuu_cardin;
		}
	}
	iuu_rxcmd(urb);
}

static void iuu_status_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	int result;
	int status = urb->status;

	dev_dbg(&port->dev, "%s - status = %d\n", __func__, status);
	usb_fill_bulk_urb(port->read_urb, port->serial->dev,
			  usb_rcvbulkpipe(port->serial->dev,
					  port->bulk_in_endpointAddress),
			  port->read_urb->transfer_buffer, 256,
			  iuu_update_status_callback, port);
	result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
}

static int iuu_status(struct usb_serial_port *port)
{
	int result;

	memset(port->write_urb->transfer_buffer, IUU_GET_STATE_REGISTER, 1);
	usb_fill_bulk_urb(port->write_urb, port->serial->dev,
			  usb_sndbulkpipe(port->serial->dev,
					  port->bulk_out_endpointAddress),
			  port->write_urb->transfer_buffer, 1,
			  iuu_status_callback, port);
	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
	return result;

}

static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
{
	int status;
	struct usb_serial *serial = port->serial;
	int actual = 0;

	/* send the data out the bulk port */

	status =
	    usb_bulk_msg(serial->dev,
			 usb_sndbulkpipe(serial->dev,
					 port->bulk_out_endpointAddress), buf,
			 count, &actual, 1000);

	if (status != IUU_OPERATION_OK)
		dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
	else
		dev_dbg(&port->dev, "%s - write OK !\n", __func__);
	return status;
}

static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count)
{
	int status;
	struct usb_serial *serial = port->serial;
	int actual = 0;

	/* send the data out the bulk port */
	status =
	    usb_bulk_msg(serial->dev,
			 usb_rcvbulkpipe(serial->dev,
					 port->bulk_in_endpointAddress), buf,
			 count, &actual, 1000);

	if (status != IUU_OPERATION_OK)
		dev_dbg(&port->dev, "%s - error = %2x\n", __func__, status);
	else
		dev_dbg(&port->dev, "%s - read OK !\n", __func__);
	return status;
}

static int iuu_led(struct usb_serial_port *port, unsigned int R,
		   unsigned int G, unsigned int B, u8 f)
{
	int status;
	u8 *buf;
	buf = kmalloc(8, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	buf[0] = IUU_SET_LED;
	buf[1] = R & 0xFF;
	buf[2] = (R >> 8) & 0xFF;
	buf[3] = G & 0xFF;
	buf[4] = (G >> 8) & 0xFF;
	buf[5] = B & 0xFF;
	buf[6] = (B >> 8) & 0xFF;
	buf[7] = f;
	status = bulk_immediate(port, buf, 8);
	kfree(buf);
	if (status != IUU_OPERATION_OK)
		dev_dbg(&port->dev, "%s - led error status = %2x\n", __func__, status);
	else
		dev_dbg(&port->dev, "%s - led OK !\n", __func__);
	return IUU_OPERATION_OK;
}

static void iuu_rgbf_fill_buffer(u8 *buf, u8 r1, u8 r2, u8 g1, u8 g2, u8 b1,
				 u8 b2, u8 freq)
{
	*buf++ = IUU_SET_LED;
	*buf++ = r1;
	*buf++ = r2;
	*buf++ = g1;
	*buf++ = g2;
	*buf++ = b1;
	*buf++ = b2;
	*buf = freq;
}

static void iuu_led_activity_on(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	int result;
	char *buf_ptr = port->write_urb->transfer_buffer;
	*buf_ptr++ = IUU_SET_LED;
	if (xmas == 1) {
		get_random_bytes(buf_ptr, 6);
		*(buf_ptr+7) = 1;
	} else {
		iuu_rgbf_fill_buffer(buf_ptr, 255, 255, 0, 0, 0, 0, 255);
	}

	usb_fill_bulk_urb(port->write_urb, port->serial->dev,
			  usb_sndbulkpipe(port->serial->dev,
					  port->bulk_out_endpointAddress),
			  port->write_urb->transfer_buffer, 8 ,
			  iuu_rxcmd, port);
	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
}

static void iuu_led_activity_off(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	int result;
	char *buf_ptr = port->write_urb->transfer_buffer;
	if (xmas == 1) {
		iuu_rxcmd(urb);
		return;
	} else {
		*buf_ptr++ = IUU_SET_LED;
		iuu_rgbf_fill_buffer(buf_ptr, 0, 0, 255, 255, 0, 0, 255);
	}
	usb_fill_bulk_urb(port->write_urb, port->serial->dev,
			  usb_sndbulkpipe(port->serial->dev,
					  port->bulk_out_endpointAddress),
			  port->write_urb->transfer_buffer, 8 ,
			  iuu_rxcmd, port);
	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
}



static int iuu_clk(struct usb_serial_port *port, int dwFrq)
{
	int status;
	struct iuu_private *priv = usb_get_serial_port_data(port);
	int Count = 0;
	u8 FrqGenAdr = 0x69;
	u8 DIV = 0;		/* 8bit */
	u8 XDRV = 0;		/* 8bit */
	u8 PUMP = 0;		/* 3bit */
	u8 PBmsb = 0;		/* 2bit */
	u8 PBlsb = 0;		/* 8bit */
	u8 PO = 0;		/* 1bit */
	u8 Q = 0;		/* 7bit */
	/* 24bit = 3bytes */
	unsigned int P = 0;
	unsigned int P2 = 0;
	int frq = (int)dwFrq;

	if (frq == 0) {
		priv->buf[Count++] = IUU_UART_WRITE_I2C;
		priv->buf[Count++] = FrqGenAdr << 1;
		priv->buf[Count++] = 0x09;
		priv->buf[Count++] = 0x00;

		status = bulk_immediate(port, (u8 *) priv->buf, Count);
		if (status != 0) {
			dev_dbg(&port->dev, "%s - write error\n", __func__);
			return status;
		}
	} else if (frq == 3579000) {
		DIV = 100;
		P = 1193;
		Q = 40;
		XDRV = 0;
	} else if (frq == 3680000) {
		DIV = 105;
		P = 161;
		Q = 5;
		XDRV = 0;
	} else if (frq == 6000000) {
		DIV = 66;
		P = 66;
		Q = 2;
		XDRV = 0x28;
	} else {
		unsigned int result = 0;
		unsigned int tmp = 0;
		unsigned int check;
		unsigned int check2;
		char found = 0x00;
		unsigned int lQ = 2;
		unsigned int lP = 2055;
		unsigned int lDiv = 4;

		for (lQ = 2; lQ <= 47 && !found; lQ++)
			for (lP = 2055; lP >= 8 && !found; lP--)
				for (lDiv = 4; lDiv <= 127 && !found; lDiv++) {
					tmp = (12000000 / lDiv) * (lP / lQ);
					if (abs((int)(tmp - frq)) <
					    abs((int)(frq - result))) {
						check2 = (12000000 / lQ);
						if (check2 < 250000)
							continue;
						check = (12000000 / lQ) * lP;
						if (check > 400000000)
							continue;
						if (check < 100000000)
							continue;
						if (lDiv < 4 || lDiv > 127)
							continue;
						result = tmp;
						P = lP;
						DIV = lDiv;
						Q = lQ;
						if (result == frq)
							found = 0x01;
					}
				}
	}
	P2 = ((P - PO) / 2) - 4;
	DIV = DIV;
	PUMP = 0x04;
	PBmsb = (P2 >> 8 & 0x03);
	PBlsb = P2 & 0xFF;
	PO = (P >> 10) & 0x01;
	Q = Q - 2;

	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/* 0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x09;
	priv->buf[Count++] = 0x20;	/* Adr = 0x09 */
	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/* 0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x0C;
	priv->buf[Count++] = DIV;	/* Adr = 0x0C */
	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/* 0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x12;
	priv->buf[Count++] = XDRV;	/* Adr = 0x12 */
	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/*  0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x13;
	priv->buf[Count++] = 0x6B;	/* Adr = 0x13 */
	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/*  0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x40;
	priv->buf[Count++] = (0xC0 | ((PUMP & 0x07) << 2)) |
			     (PBmsb & 0x03);	/* Adr = 0x40 */
	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/*  0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x41;
	priv->buf[Count++] = PBlsb;	/* Adr = 0x41 */
	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/*  0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x42;
	priv->buf[Count++] = Q | (((PO & 0x01) << 7));	/* Adr = 0x42 */
	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/*  0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x44;
	priv->buf[Count++] = (char)0xFF;	/* Adr = 0x44 */
	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/*  0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x45;
	priv->buf[Count++] = (char)0xFE;	/* Adr = 0x45 */
	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/*  0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x46;
	priv->buf[Count++] = 0x7F;	/* Adr = 0x46 */
	priv->buf[Count++] = IUU_UART_WRITE_I2C;	/*  0x4C */
	priv->buf[Count++] = FrqGenAdr << 1;
	priv->buf[Count++] = 0x47;
	priv->buf[Count++] = (char)0x84;	/* Adr = 0x47 */

	status = bulk_immediate(port, (u8 *) priv->buf, Count);
	if (status != IUU_OPERATION_OK)
		dev_dbg(&port->dev, "%s - write error\n", __func__);
	return status;
}

static int iuu_uart_flush(struct usb_serial_port *port)
{
	struct device *dev = &port->dev;
	int i;
	int status;
	u8 rxcmd = IUU_UART_RX;
	struct iuu_private *priv = usb_get_serial_port_data(port);

	if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0)
		return -EIO;

	for (i = 0; i < 2; i++) {
		status = bulk_immediate(port, &rxcmd, 1);
		if (status != IUU_OPERATION_OK) {
			dev_dbg(dev, "%s - uart_flush_write error\n", __func__);
			return status;
		}

		status = read_immediate(port, &priv->len, 1);
		if (status != IUU_OPERATION_OK) {
			dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
			return status;
		}

		if (priv->len > 0) {
			dev_dbg(dev, "%s - uart_flush datalen is : %i\n", __func__, priv->len);
			status = read_immediate(port, priv->buf, priv->len);
			if (status != IUU_OPERATION_OK) {
				dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
				return status;
			}
		}
	}
	dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__);
	iuu_led(port, 0, 0xF000, 0, 0xFF);
	return status;
}

static void read_buf_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	unsigned char *data = urb->transfer_buffer;
	int status = urb->status;

	if (status) {
		if (status == -EPROTO) {
			/* reschedule needed */
		}
		return;
	}

	dev_dbg(&port->dev, "%s - %i chars to write\n", __func__, urb->actual_length);
	if (data == NULL)
		dev_dbg(&port->dev, "%s - data is NULL !!!\n", __func__);
	if (urb->actual_length && data) {
		tty_insert_flip_string(&port->port, data, urb->actual_length);
		tty_flip_buffer_push(&port->port);
	}
	iuu_led_activity_on(urb);
}

static int iuu_bulk_write(struct usb_serial_port *port)
{
	struct iuu_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	int result;
	int buf_len;
	char *buf_ptr = port->write_urb->transfer_buffer;

	spin_lock_irqsave(&priv->lock, flags);
	*buf_ptr++ = IUU_UART_ESC;
	*buf_ptr++ = IUU_UART_TX;
	*buf_ptr++ = priv->writelen;

	memcpy(buf_ptr, priv->writebuf, priv->writelen);
	buf_len = priv->writelen;
	priv->writelen = 0;
	spin_unlock_irqrestore(&priv->lock, flags);
	dev_dbg(&port->dev, "%s - writing %i chars : %*ph\n", __func__,
		buf_len, buf_len, buf_ptr);
	usb_fill_bulk_urb(port->write_urb, port->serial->dev,
			  usb_sndbulkpipe(port->serial->dev,
					  port->bulk_out_endpointAddress),
			  port->write_urb->transfer_buffer, buf_len + 3,
			  iuu_rxcmd, port);
	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
	usb_serial_port_softint(port);
	return result;
}

static int iuu_read_buf(struct usb_serial_port *port, int len)
{
	int result;

	usb_fill_bulk_urb(port->read_urb, port->serial->dev,
			  usb_rcvbulkpipe(port->serial->dev,
					  port->bulk_in_endpointAddress),
			  port->read_urb->transfer_buffer, len,
			  read_buf_callback, port);
	result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
	return result;
}

static void iuu_uart_read_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	struct iuu_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	int status = urb->status;
	int error = 0;
	int len = 0;
	unsigned char *data = urb->transfer_buffer;
	priv->poll++;

	if (status) {
		dev_dbg(&port->dev, "%s - status = %d\n", __func__, status);
		/* error stop all */
		return;
	}
	if (data == NULL)
		dev_dbg(&port->dev, "%s - data is NULL !!!\n", __func__);

	if (urb->actual_length == 1  && data != NULL)
		len = (int) data[0];

	if (urb->actual_length > 1) {
		dev_dbg(&port->dev, "%s - urb->actual_length = %i\n", __func__,
		    urb->actual_length);
		error = 1;
		return;
	}
	/* if len > 0 call readbuf */

	if (len > 0 && error == 0) {
		dev_dbg(&port->dev, "%s - call read buf - len to read is %i\n",
			__func__, len);
		status = iuu_read_buf(port, len);
		return;
	}
	/* need to update status  ? */
	if (priv->poll > 99) {
		status = iuu_status(port);
		priv->poll = 0;
		return;
	}

	/* reset waiting ? */

	if (priv->reset == 1) {
		status = iuu_reset(port, 0xC);
		return;
	}
	/* Writebuf is waiting */
	spin_lock_irqsave(&priv->lock, flags);
	if (priv->writelen > 0) {
		spin_unlock_irqrestore(&priv->lock, flags);
		status = iuu_bulk_write(port);
		return;
	}
	spin_unlock_irqrestore(&priv->lock, flags);
	/* if nothing to write call again rxcmd */
	dev_dbg(&port->dev, "%s - rxcmd recall\n", __func__);
	iuu_led_activity_off(urb);
}

static int iuu_uart_write(struct tty_struct *tty, struct usb_serial_port *port,
			  const u8 *buf, int count)
{
	struct iuu_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;

	if (count > 256)
		return -ENOMEM;

	spin_lock_irqsave(&priv->lock, flags);

	/* fill the buffer */
	memcpy(priv->writebuf + priv->writelen, buf, count);
	priv->writelen += count;
	spin_unlock_irqrestore(&priv->lock, flags);

	return count;
}

static void read_rxcmd_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	int result;
	int status = urb->status;

	if (status) {
		/* error stop all */
		return;
	}

	usb_fill_bulk_urb(port->read_urb, port->serial->dev,
			  usb_rcvbulkpipe(port->serial->dev,
					  port->bulk_in_endpointAddress),
			  port->read_urb->transfer_buffer, 256,
			  iuu_uart_read_callback, port);
	result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
	dev_dbg(&port->dev, "%s - submit result = %d\n", __func__, result);
}

static int iuu_uart_on(struct usb_serial_port *port)
{
	int status;
	u8 *buf;

	buf = kmalloc(sizeof(u8) * 4, GFP_KERNEL);

	if (!buf)
		return -ENOMEM;

	buf[0] = IUU_UART_ENABLE;
	buf[1] = (u8) ((IUU_BAUD_9600 >> 8) & 0x00FF);
	buf[2] = (u8) (0x00FF & IUU_BAUD_9600);
	buf[3] = (u8) (0x0F0 & IUU_ONE_STOP_BIT) | (0x07 & IUU_PARITY_EVEN);

	status = bulk_immediate(port, buf, 4);
	if (status != IUU_OPERATION_OK) {
		dev_dbg(&port->dev, "%s - uart_on error\n", __func__);
		goto uart_enable_failed;
	}
	/*  iuu_reset() the card after iuu_uart_on() */
	status = iuu_uart_flush(port);
	if (status != IUU_OPERATION_OK)
		dev_dbg(&port->dev, "%s - uart_flush error\n", __func__);
uart_enable_failed:
	kfree(buf);
	return status;
}

/*  Disables the IUU UART (a.k.a. the Phoenix voiderface) */
static int iuu_uart_off(struct usb_serial_port *port)
{
	int status;
	u8 *buf;
	buf = kmalloc(1, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
	buf[0] = IUU_UART_DISABLE;

	status = bulk_immediate(port, buf, 1);
	if (status != IUU_OPERATION_OK)
		dev_dbg(&port->dev, "%s - uart_off error\n", __func__);

	kfree(buf);
	return status;
}

static int iuu_uart_baud(struct usb_serial_port *port, u32 baud_base,
			 u32 *actual, u8 parity)
{
	int status;
	u32 baud;
	u8 *dataout;
	u8 DataCount = 0;
	u8 T1Frekvens = 0;
	u8 T1reload = 0;
	unsigned int T1FrekvensHZ = 0;

	dev_dbg(&port->dev, "%s - enter baud_base=%d\n", __func__, baud_base);
	dataout = kmalloc(sizeof(u8) * 5, GFP_KERNEL);

	if (!dataout)
		return -ENOMEM;
	/*baud = (((priv->clk / 35) * baud_base) / 100000); */
	baud = baud_base;

	if (baud < 1200 || baud > 230400) {
		kfree(dataout);
		return IUU_INVALID_PARAMETER;
	}
	if (baud > 977) {
		T1Frekvens = 3;
		T1FrekvensHZ = 500000;
	}

	if (baud > 3906) {
		T1Frekvens = 2;
		T1FrekvensHZ = 2000000;
	}

	if (baud > 11718) {
		T1Frekvens = 1;
		T1FrekvensHZ = 6000000;
	}

	if (baud > 46875) {
		T1Frekvens = 0;
		T1FrekvensHZ = 24000000;
	}

	T1reload = 256 - (u8) (T1FrekvensHZ / (baud * 2));

	/*  magic number here:  ENTER_FIRMWARE_UPDATE; */
	dataout[DataCount++] = IUU_UART_ESC;
	/*  magic number here:  CHANGE_BAUD; */
	dataout[DataCount++] = IUU_UART_CHANGE;
	dataout[DataCount++] = T1Frekvens;
	dataout[DataCount++] = T1reload;

	*actual = (T1FrekvensHZ / (256 - T1reload)) / 2;

	switch (parity & 0x0F) {
	case IUU_PARITY_NONE:
		dataout[DataCount++] = 0x00;
		break;
	case IUU_PARITY_EVEN:
		dataout[DataCount++] = 0x01;
		break;
	case IUU_PARITY_ODD:
		dataout[DataCount++] = 0x02;
		break;
	case IUU_PARITY_MARK:
		dataout[DataCount++] = 0x03;
		break;
	case IUU_PARITY_SPACE:
		dataout[DataCount++] = 0x04;
		break;
	default:
		kfree(dataout);
		return IUU_INVALID_PARAMETER;
		break;
	}

	switch (parity & 0xF0) {
	case IUU_ONE_STOP_BIT:
		dataout[DataCount - 1] |= IUU_ONE_STOP_BIT;
		break;

	case IUU_TWO_STOP_BITS:
		dataout[DataCount - 1] |= IUU_TWO_STOP_BITS;
		break;
	default:
		kfree(dataout);
		return IUU_INVALID_PARAMETER;
		break;
	}

	status = bulk_immediate(port, dataout, DataCount);
	if (status != IUU_OPERATION_OK)
		dev_dbg(&port->dev, "%s - uart_off error\n", __func__);
	kfree(dataout);
	return status;
}

static void iuu_set_termios(struct tty_struct *tty,
		struct usb_serial_port *port, struct ktermios *old_termios)
{
	const u32 supported_mask = CMSPAR|PARENB|PARODD;
	struct iuu_private *priv = usb_get_serial_port_data(port);
	unsigned int cflag = tty->termios.c_cflag;
	int status;
	u32 actual;
	u32 parity;
	int csize = CS7;
	int baud;
	u32 newval = cflag & supported_mask;

	/* Just use the ospeed. ispeed should be the same. */
	baud = tty->termios.c_ospeed;

	dev_dbg(&port->dev, "%s - enter c_ospeed or baud=%d\n", __func__, baud);

	/* compute the parity parameter */
	parity = 0;
	if (cflag & CMSPAR) {	/* Using mark space */
		if (cflag & PARODD)
			parity |= IUU_PARITY_SPACE;
		else
			parity |= IUU_PARITY_MARK;
	} else if (!(cflag & PARENB)) {
		parity |= IUU_PARITY_NONE;
		csize = CS8;
	} else if (cflag & PARODD)
		parity |= IUU_PARITY_ODD;
	else
		parity |= IUU_PARITY_EVEN;

	parity |= (cflag & CSTOPB ? IUU_TWO_STOP_BITS : IUU_ONE_STOP_BIT);

	/* set it */
	status = iuu_uart_baud(port,
			baud * priv->boost / 100,
			&actual, parity);

	/* set the termios value to the real one, so the user now what has
	 * changed. We support few fields so its easies to copy the old hw
	 * settings back over and then adjust them
	 */
	if (old_termios)
		tty_termios_copy_hw(&tty->termios, old_termios);
	if (status != 0)	/* Set failed - return old bits */
		return;
	/* Re-encode speed, parity and csize */
	tty_encode_baud_rate(tty, baud, baud);
	tty->termios.c_cflag &= ~(supported_mask|CSIZE);
	tty->termios.c_cflag |= newval | csize;
}

static void iuu_close(struct usb_serial_port *port)
{
	/* iuu_led (port,255,0,0,0); */

	iuu_uart_off(port);

	usb_kill_urb(port->write_urb);
	usb_kill_urb(port->read_urb);

	iuu_led(port, 0, 0, 0xF000, 0xFF);
}

static void iuu_init_termios(struct tty_struct *tty)
{
	tty->termios = tty_std_termios;
	tty->termios.c_cflag = CLOCAL | CREAD | CS8 | B9600
				| TIOCM_CTS | CSTOPB | PARENB;
	tty->termios.c_ispeed = 9600;
	tty->termios.c_ospeed = 9600;
	tty->termios.c_lflag = 0;
	tty->termios.c_oflag = 0;
	tty->termios.c_iflag = 0;
}

static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
{
	struct usb_serial *serial = port->serial;
	struct device *dev = &port->dev;
	u8 *buf;
	int result;
	int baud;
	u32 actual;
	struct iuu_private *priv = usb_get_serial_port_data(port);

	baud = tty->termios.c_ospeed;
	tty->termios.c_ispeed = baud;
	/* Re-encode speed */
	tty_encode_baud_rate(tty, baud, baud);

	dev_dbg(dev, "%s - baud %d\n", __func__, baud);
	usb_clear_halt(serial->dev, port->write_urb->pipe);
	usb_clear_halt(serial->dev, port->read_urb->pipe);

	buf = kmalloc(10, GFP_KERNEL);
	if (buf == NULL)
		return -ENOMEM;

	priv->poll = 0;

	/* initialize writebuf */
#define FISH(a, b, c, d) do { \
	result = usb_control_msg(port->serial->dev,	\
				usb_rcvctrlpipe(port->serial->dev, 0),	\
				b, a, c, d, buf, 1, 1000); \
	dev_dbg(dev, "0x%x:0x%x:0x%x:0x%x  %d - %x\n", a, b, c, d, result, \
				buf[0]); } while (0);

#define SOUP(a, b, c, d)  do { \
	result = usb_control_msg(port->serial->dev,	\
				usb_sndctrlpipe(port->serial->dev, 0),	\
				b, a, c, d, NULL, 0, 1000); \
	dev_dbg(dev, "0x%x:0x%x:0x%x:0x%x  %d\n", a, b, c, d, result); } while (0)

	/*  This is not UART related but IUU USB driver related or something */
	/*  like that. Basically no IUU will accept any commands from the USB */
	/*  host unless it has received the following message */
	/* sprintf(buf ,"%c%c%c%c",0x03,0x02,0x02,0x0); */

	SOUP(0x03, 0x02, 0x02, 0x0);
	kfree(buf);
	iuu_led(port, 0xF000, 0xF000, 0, 0xFF);
	iuu_uart_on(port);
	if (boost < 100)
		boost = 100;
	priv->boost = boost;
	priv->baud = baud;
	switch (clockmode) {
	case 2:		/*  3.680 Mhz */
		priv->clk = IUU_CLK_3680000;
		iuu_clk(port, IUU_CLK_3680000 * boost / 100);
		result =
		    iuu_uart_baud(port, baud * boost / 100, &actual,
				  IUU_PARITY_EVEN);
		break;
	case 3:		/*  6.00 Mhz */
		iuu_clk(port, IUU_CLK_6000000 * boost / 100);
		priv->clk = IUU_CLK_6000000;
		/* Ratio of 6000000 to 3500000 for baud 9600 */
		result =
		    iuu_uart_baud(port, 16457 * boost / 100, &actual,
				  IUU_PARITY_EVEN);
		break;
	default:		/*  3.579 Mhz */
		iuu_clk(port, IUU_CLK_3579000 * boost / 100);
		priv->clk = IUU_CLK_3579000;
		result =
		    iuu_uart_baud(port, baud * boost / 100, &actual,
				  IUU_PARITY_EVEN);
	}

	/* set the cardin cardout signals */
	switch (cdmode) {
	case 0:
		iuu_cardin = 0;
		iuu_cardout = 0;
		break;
	case 1:
		iuu_cardin = TIOCM_CD;
		iuu_cardout =  0;
		break;
	case 2:
		iuu_cardin = 0;
		iuu_cardout = TIOCM_CD;
		break;
	case 3:
		iuu_cardin = TIOCM_DSR;
		iuu_cardout = 0;
		break;
	case 4:
		iuu_cardin = 0;
		iuu_cardout = TIOCM_DSR;
		break;
	case 5:
		iuu_cardin = TIOCM_CTS;
		iuu_cardout = 0;
		break;
	case 6:
		iuu_cardin = 0;
		iuu_cardout = TIOCM_CTS;
		break;
	case 7:
		iuu_cardin = TIOCM_RNG;
		iuu_cardout = 0;
		break;
	case 8:
		iuu_cardin = 0;
		iuu_cardout = TIOCM_RNG;
	}

	iuu_uart_flush(port);

	dev_dbg(dev, "%s - initialization done\n", __func__);

	memset(port->write_urb->transfer_buffer, IUU_UART_RX, 1);
	usb_fill_bulk_urb(port->write_urb, port->serial->dev,
			  usb_sndbulkpipe(port->serial->dev,
					  port->bulk_out_endpointAddress),
			  port->write_urb->transfer_buffer, 1,
			  read_rxcmd_callback, port);
	result = usb_submit_urb(port->write_urb, GFP_KERNEL);
	if (result) {
		dev_err(dev, "%s - failed submitting read urb, error %d\n", __func__, result);
		iuu_close(port);
	} else {
		dev_dbg(dev, "%s - rxcmd OK\n", __func__);
	}

	return result;
}

/* how to change VCC */
static int iuu_vcc_set(struct usb_serial_port *port, unsigned int vcc)
{
	int status;
	u8 *buf;

	buf = kmalloc(5, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	buf[0] = IUU_SET_VCC;
	buf[1] = vcc & 0xFF;
	buf[2] = (vcc >> 8) & 0xFF;
	buf[3] = (vcc >> 16) & 0xFF;
	buf[4] = (vcc >> 24) & 0xFF;

	status = bulk_immediate(port, buf, 5);
	kfree(buf);

	if (status != IUU_OPERATION_OK)
		dev_dbg(&port->dev, "%s - vcc error status = %2x\n", __func__, status);
	else
		dev_dbg(&port->dev, "%s - vcc OK !\n", __func__);

	return status;
}

/*
 * Sysfs Attributes
 */

static ssize_t vcc_mode_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct usb_serial_port *port = to_usb_serial_port(dev);
	struct iuu_private *priv = usb_get_serial_port_data(port);

	return sprintf(buf, "%d\n", priv->vcc);
}

static ssize_t vcc_mode_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	struct usb_serial_port *port = to_usb_serial_port(dev);
	struct iuu_private *priv = usb_get_serial_port_data(port);
	unsigned long v;

	if (kstrtoul(buf, 10, &v)) {
		dev_err(dev, "%s - vcc_mode: %s is not a unsigned long\n",
				__func__, buf);
		goto fail_store_vcc_mode;
	}

	dev_dbg(dev, "%s: setting vcc_mode = %ld\n", __func__, v);

	if ((v != 3) && (v != 5)) {
		dev_err(dev, "%s - vcc_mode %ld is invalid\n", __func__, v);
	} else {
		iuu_vcc_set(port, v);
		priv->vcc = v;
	}
fail_store_vcc_mode:
	return count;
}
static DEVICE_ATTR_RW(vcc_mode);

static int iuu_create_sysfs_attrs(struct usb_serial_port *port)
{
	return device_create_file(&port->dev, &dev_attr_vcc_mode);
}

static int iuu_remove_sysfs_attrs(struct usb_serial_port *port)
{
	device_remove_file(&port->dev, &dev_attr_vcc_mode);
	return 0;
}

/*
 * End Sysfs Attributes
 */

static struct usb_serial_driver iuu_device = {
	.driver = {
		   .owner = THIS_MODULE,
		   .name = "iuu_phoenix",
		   },
	.id_table = id_table,
	.num_ports = 1,
	.bulk_in_size = 512,
	.bulk_out_size = 512,
	.open = iuu_open,
	.close = iuu_close,
	.write = iuu_uart_write,
	.read_bulk_callback = iuu_uart_read_callback,
	.tiocmget = iuu_tiocmget,
	.tiocmset = iuu_tiocmset,
	.set_termios = iuu_set_termios,
	.init_termios = iuu_init_termios,
	.port_probe = iuu_port_probe,
	.port_remove = iuu_port_remove,
};

static struct usb_serial_driver * const serial_drivers[] = {
	&iuu_device, NULL
};

module_usb_serial_driver(serial_drivers, id_table);

MODULE_AUTHOR("Alain Degreffe eczema@ecze.com");

MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

module_param(xmas, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(xmas, "Xmas colors enabled or not");

module_param(boost, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(boost, "Card overclock boost (in percent 100-500)");

module_param(clockmode, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(clockmode, "Card clock mode (1=3.579 MHz, 2=3.680 MHz, "
		"3=6 Mhz)");

module_param(cdmode, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(cdmode, "Card detect mode (0=none, 1=CD, 2=!CD, 3=DSR, "
		 "4=!DSR, 5=CTS, 6=!CTS, 7=RING, 8=!RING)");

module_param(vcc_default, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(vcc_default, "Set default VCC (either 3 for 3.3V or 5 "
		"for 5V). Default to 5.");
