#include <linux/version.h>
#include <media/saa7146_vv.h>

static u32 saa7146_i2c_func(struct i2c_adapter *adapter)
{
//fm	DEB_I2C(("'%s'.\n", adapter->name));

	return	  I2C_FUNC_I2C
		| I2C_FUNC_SMBUS_QUICK
		| I2C_FUNC_SMBUS_READ_BYTE	| I2C_FUNC_SMBUS_WRITE_BYTE
		| I2C_FUNC_SMBUS_READ_BYTE_DATA | I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
}

/* this function returns the status-register of our i2c-device */
static inline u32 saa7146_i2c_status(struct saa7146_dev *dev)
{
	u32 iicsta = saa7146_read(dev, I2C_STATUS);
/*
	DEB_I2C(("status: 0x%08x\n",iicsta));
*/
	return iicsta;
}

/* this function runs through the i2c-messages and prepares the data to be
   sent through the saa7146. have a look at the specifications p. 122 ff
   to understand this. it returns the number of u32s to send, or -1
   in case of an error. */
static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op)
{
	int h1, h2;
	int i, j, addr;
	int mem = 0, op_count = 0;

	/* first determine size of needed memory */
	for(i = 0; i < num; i++) {
		mem += m[i].len + 1;
	}

	/* worst case: we need one u32 for three bytes to be send
	   plus one extra byte to address the device */
	mem = 1 + ((mem-1) / 3);

	/* we assume that op points to a memory of at least SAA7146_I2C_MEM bytes
	   size. if we exceed this limit... */
	if ( (4*mem) > SAA7146_I2C_MEM ) {
//fm		DEB_I2C(("cannot prepare i2c-message.\n"));
		return -ENOMEM;
	}

	/* be careful: clear out the i2c-mem first */
	memset(op,0,sizeof(u32)*mem);

	/* loop through all messages */
	for(i = 0; i < num; i++) {

		/* insert the address of the i2c-slave.
		   note: we get 7 bit i2c-addresses,
		   so we have to perform a translation */
		addr = (m[i].addr*2) + ( (0 != (m[i].flags & I2C_M_RD)) ? 1 : 0);
		h1 = op_count/3; h2 = op_count%3;
		op[h1] |= (	    (u8)addr << ((3-h2)*8));
		op[h1] |= (SAA7146_I2C_START << ((3-h2)*2));
		op_count++;

		/* loop through all bytes of message i */
		for(j = 0; j < m[i].len; j++) {
			/* insert the data bytes */
			h1 = op_count/3; h2 = op_count%3;
			op[h1] |= ( (u32)((u8)m[i].buf[j]) << ((3-h2)*8));
			op[h1] |= (       SAA7146_I2C_CONT << ((3-h2)*2));
			op_count++;
		}

	}

	/* have a look at the last byte inserted:
	  if it was: ...CONT change it to ...STOP */
	h1 = (op_count-1)/3; h2 = (op_count-1)%3;
	if ( SAA7146_I2C_CONT == (0x3 & (op[h1] >> ((3-h2)*2))) ) {
		op[h1] &= ~(0x2 << ((3-h2)*2));
		op[h1] |= (SAA7146_I2C_STOP << ((3-h2)*2));
	}

	/* return the number of u32s to send */
	return mem;
}

/* this functions loops through all i2c-messages. normally, it should determine
   which bytes were read through the adapter and write them back to the corresponding
   i2c-message. but instead, we simply write back all bytes.
   fixme: this could be improved. */
static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, u32 *op)
{
	int i, j;
	int op_count = 0;

	/* loop through all messages */
	for(i = 0; i < num; i++) {

		op_count++;

		/* loop throgh all bytes of message i */
		for(j = 0; j < m[i].len; j++) {
			/* write back all bytes that could have been read */
			m[i].buf[j] = (op[op_count/3] >> ((3-(op_count%3))*8));
			op_count++;
		}
	}

	return 0;
}

/* this functions resets the i2c-device and returns 0 if everything was fine, otherwise -1 */
static int saa7146_i2c_reset(struct saa7146_dev *dev)
{
	/* get current status */
	u32 status = saa7146_i2c_status(dev);

	/* clear registers for sure */
	saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
	saa7146_write(dev, I2C_TRANSFER, 0);

	/* check if any operation is still in progress */
	if ( 0 != ( status & SAA7146_I2C_BUSY) ) {

		/* yes, kill ongoing operation */
		DEB_I2C(("busy_state detected.\n"));

		/* set "ABORT-OPERATION"-bit (bit 7)*/
		saa7146_write(dev, I2C_STATUS, (dev->i2c_bitrate | MASK_07));
		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
		msleep(SAA7146_I2C_DELAY);

		/* clear all error-bits pending; this is needed because p.123, note 1 */
		saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
		msleep(SAA7146_I2C_DELAY);
	}

	/* check if any error is (still) present. (this can be necessary because p.123, note 1) */
	status = saa7146_i2c_status(dev);

	if ( dev->i2c_bitrate != status ) {

		DEB_I2C(("error_state detected. status:0x%08x\n",status));

		/* Repeat the abort operation. This seems to be necessary
		   after serious protocol errors caused by e.g. the SAA7740 */
		saa7146_write(dev, I2C_STATUS, (dev->i2c_bitrate | MASK_07));
		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
		msleep(SAA7146_I2C_DELAY);

		/* clear all error-bits pending */
		saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
		msleep(SAA7146_I2C_DELAY);

		/* the data sheet says it might be necessary to clear the status
		   twice after an abort */
		saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
		msleep(SAA7146_I2C_DELAY);
	}

	/* if any error is still present, a fatal error has occured ... */
	status = saa7146_i2c_status(dev);
	if ( dev->i2c_bitrate != status ) {
		DEB_I2C(("fatal error. status:0x%08x\n",status));
		return -1;
	}

	return 0;
}

/* this functions writes out the data-byte 'dword' to the i2c-device.
   it returns 0 if ok, -1 if the transfer failed, -2 if the transfer
   failed badly (e.g. address error) */
static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_delay)
{
	u32 status = 0, mc2 = 0;
	int trial = 0;
	unsigned long timeout;

	/* write out i2c-command */
	DEB_I2C(("before: 0x%08x (status: 0x%08x), %d\n",*dword,saa7146_read(dev, I2C_STATUS), dev->i2c_op));

	if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {

		saa7146_write(dev, I2C_STATUS,	 dev->i2c_bitrate);
		saa7146_write(dev, I2C_TRANSFER, *dword);

		dev->i2c_op = 1;
		SAA7146_IER_ENABLE(dev, MASK_16|MASK_17);
		saa7146_write(dev, MC2, (MASK_00 | MASK_16));

		wait_event_interruptible(dev->i2c_wq, dev->i2c_op == 0);
		if (signal_pending (current)) {
			/* a signal arrived */
			return -ERESTARTSYS;
		}
		status = saa7146_read(dev, I2C_STATUS);
	} else {
		saa7146_write(dev, I2C_STATUS,	 dev->i2c_bitrate);
		saa7146_write(dev, I2C_TRANSFER, *dword);
		saa7146_write(dev, MC2, (MASK_00 | MASK_16));

		/* do not poll for i2c-status before upload is complete */
		timeout = jiffies + HZ/100 + 1; /* 10ms */
		while(1) {
			mc2 = (saa7146_read(dev, MC2) & 0x1);
			if( 0 != mc2 ) {
				break;
			}
			if (time_after(jiffies,timeout)) {
				printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for MC2\n");
				return -EIO;
			}
		}
		/* wait until we get a transfer done or error */
		timeout = jiffies + HZ/100 + 1; /* 10ms */
		while(1) {
			/**
			 *  first read usually delivers bogus results...
			 */
			saa7146_i2c_status(dev);
			status = saa7146_i2c_status(dev);
			if ((status & 0x3) != 1)
				break;
			if (time_after(jiffies,timeout)) {
				/* this is normal when probing the bus
				 * (no answer from nonexisistant device...)
				 */
				DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
				return -EIO;
			}
			if ((++trial < 20) && short_delay)
				udelay(10);
			else
			msleep(1);
		}
	}

	/* give a detailed status report */
	if ( 0 != (status & SAA7146_I2C_ERR)) {

		if( 0 != (status & SAA7146_I2C_SPERR) ) {
			DEB_I2C(("error due to invalid start/stop condition.\n"));
		}
		if( 0 != (status & SAA7146_I2C_DTERR) ) {
			DEB_I2C(("error in data transmission.\n"));
		}
		if( 0 != (status & SAA7146_I2C_DRERR) ) {
			DEB_I2C(("error when receiving data.\n"));
		}
		if( 0 != (status & SAA7146_I2C_AL) ) {
			DEB_I2C(("error because arbitration lost.\n"));
		}

		/* we handle address-errors here */
		if( 0 != (status & SAA7146_I2C_APERR) ) {
			DEB_I2C(("error in address phase.\n"));
			return -EREMOTEIO;
		}

		return -EIO;
	}

	/* read back data, just in case we were reading ... */
	*dword = saa7146_read(dev, I2C_TRANSFER);

	DEB_I2C(("after: 0x%08x\n",*dword));
	return 0;
}

int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries)
{
	int i = 0, count = 0;
	u32* buffer = dev->d_i2c.cpu_addr;
	int err = 0;
        int address_err = 0;
        int short_delay = 0;

	if (down_interruptible (&dev->i2c_lock))
		return -ERESTARTSYS;

	for(i=0;i<num;i++) {
		DEB_I2C(("msg:%d/%d\n",i+1,num));
	}

	/* prepare the message(s), get number of u32s to transfer */
	count = saa7146_i2c_msg_prepare(msgs, num, buffer);
	if ( 0 > count ) {
		err = -1;
		goto out;
	}

	if ( count > 3 || 0 != (SAA7146_I2C_SHORT_DELAY & dev->ext->flags) )
		short_delay = 1;

	do {
		/* reset the i2c-device if necessary */
		err = saa7146_i2c_reset(dev);
		if ( 0 > err ) {
			DEB_I2C(("could not reset i2c-device.\n"));
			goto out;
		}

		/* write out the u32s one after another */
		for(i = 0; i < count; i++) {
			err = saa7146_i2c_writeout(dev, &buffer[i], short_delay);
			if ( 0 != err) {
				/* this one is unsatisfying: some i2c slaves on some
				   dvb cards don't acknowledge correctly, so the saa7146
				   thinks that an address error occured. in that case, the
				   transaction should be retrying, even if an address error
				   occured. analog saa7146 based cards extensively rely on
				   i2c address probing, however, and address errors indicate that a
				   device is really *not* there. retrying in that case
				   increases the time the device needs to probe greatly, so
				   it should be avoided. because of the fact, that only
				   analog based cards use irq based i2c transactions (for dvb
				   cards, this screwes up other interrupt sources), we bail out
				   completely for analog cards after an address error and trust
				   the saa7146 address error detection. */
				if ( -EREMOTEIO == err ) {
					if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
						goto out;
					}
				        address_err++;
				}
				DEB_I2C(("error while sending message(s). starting again.\n"));
				break;
			}
		}
		if( 0 == err ) {
			err = num;
			break;
		}

	        /* delay a bit before retrying */
	        msleep(10);

	} while (err != num && retries--);

        /* if every retry had an address error, exit right away */
        if (address_err == retries) {
	        goto out;
	}

	/* if any things had to be read, get the results */
	if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) {
		DEB_I2C(("could not cleanup i2c-message.\n"));
		err = -1;
		goto out;
	}

	/* return the number of delivered messages */
	DEB_I2C(("transmission successful. (msg:%d).\n",err));
out:
	/* another bug in revision 0: the i2c-registers get uploaded randomly by other
	   uploads, so we better clear them out before continueing */
	if( 0 == dev->revision ) {
		u32 zero = 0;
		saa7146_i2c_reset(dev);
		if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) {
			INFO(("revision 0 error. this should never happen.\n"));
		}
	}

	up(&dev->i2c_lock);
	return err;
}

/* utility functions */
static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
{
	struct saa7146_dev* dev = i2c_get_adapdata(adapter);

	/* use helper function to transfer data */
	return saa7146_i2c_transfer(dev, msg, num, adapter->retries);
}


/*****************************************************************************/
/* i2c-adapter helper functions                                              */
#include <linux/i2c-id.h>

/* exported algorithm data */
static struct i2c_algorithm saa7146_algo = {
	.name		= "saa7146 i2c algorithm",
	.id		= I2C_ALGO_SAA7146,
	.master_xfer	= saa7146_i2c_xfer,
	.functionality	= saa7146_i2c_func,
};

int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate)
{
	DEB_EE(("bitrate: 0x%08x\n",bitrate));

	/* enable i2c-port pins */
	saa7146_write(dev, MC1, (MASK_08 | MASK_24));

	dev->i2c_bitrate = bitrate;
	saa7146_i2c_reset(dev);

	if( NULL != i2c_adapter ) {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
		i2c_adapter->data = dev;
#else
		BUG_ON(!i2c_adapter->class);
		i2c_set_adapdata(i2c_adapter,dev);
#endif
		i2c_adapter->algo	   = &saa7146_algo;
		i2c_adapter->algo_data     = NULL;
		i2c_adapter->id		   = I2C_ALGO_SAA7146;
		i2c_adapter->timeout = SAA7146_I2C_TIMEOUT;
		i2c_adapter->retries = SAA7146_I2C_RETRIES;
	}

	return 0;
}
