/*
 * Coral-P(A)/Lime I2C adapter driver
 *
 * (C) 2011 DENX Software Engineering, Anatolij Gustschin <agust@denx.de>
 *
 * 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.
 *
 */

#include <linux/fb.h>
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/delay.h>

#include "mb862xxfb.h"
#include "mb862xx_reg.h"

static int mb862xx_i2c_wait_event(struct i2c_adapter *adap)
{
	struct mb862xxfb_par *par = adap->algo_data;
	u32 reg;

	do {
		udelay(10);
		reg = inreg(i2c, GC_I2C_BCR);
		if (reg & (I2C_INT | I2C_BER))
			break;
	} while (1);

	return (reg & I2C_BER) ? 0 : 1;
}

static int mb862xx_i2c_do_address(struct i2c_adapter *adap, int addr)
{
	struct mb862xxfb_par *par = adap->algo_data;

	outreg(i2c, GC_I2C_DAR, addr);
	outreg(i2c, GC_I2C_CCR, I2C_CLOCK_AND_ENABLE);
	outreg(i2c, GC_I2C_BCR, par->i2c_rs ? I2C_REPEATED_START : I2C_START);
	if (!mb862xx_i2c_wait_event(adap))
		return -EIO;
	par->i2c_rs = !(inreg(i2c, GC_I2C_BSR) & I2C_LRB);
	return par->i2c_rs;
}

static int mb862xx_i2c_write_byte(struct i2c_adapter *adap, u8 byte)
{
	struct mb862xxfb_par *par = adap->algo_data;

	outreg(i2c, GC_I2C_DAR, byte);
	outreg(i2c, GC_I2C_BCR, I2C_START);
	if (!mb862xx_i2c_wait_event(adap))
		return -EIO;
	return !(inreg(i2c, GC_I2C_BSR) & I2C_LRB);
}

static int mb862xx_i2c_read_byte(struct i2c_adapter *adap, u8 *byte, int last)
{
	struct mb862xxfb_par *par = adap->algo_data;

	outreg(i2c, GC_I2C_BCR, I2C_START | (last ? 0 : I2C_ACK));
	if (!mb862xx_i2c_wait_event(adap))
		return 0;
	*byte = inreg(i2c, GC_I2C_DAR);
	return 1;
}

void mb862xx_i2c_stop(struct i2c_adapter *adap)
{
	struct mb862xxfb_par *par = adap->algo_data;

	outreg(i2c, GC_I2C_BCR, I2C_STOP);
	outreg(i2c, GC_I2C_CCR, I2C_DISABLE);
	par->i2c_rs = 0;
}

static int mb862xx_i2c_read(struct i2c_adapter *adap, struct i2c_msg *m)
{
	int i, ret = 0;
	int last = m->len - 1;

	for (i = 0; i < m->len; i++) {
		if (!mb862xx_i2c_read_byte(adap, &m->buf[i], i == last)) {
			ret = -EIO;
			break;
		}
	}
	return ret;
}

static int mb862xx_i2c_write(struct i2c_adapter *adap, struct i2c_msg *m)
{
	int i, ret = 0;

	for (i = 0; i < m->len; i++) {
		if (!mb862xx_i2c_write_byte(adap, m->buf[i])) {
			ret = -EIO;
			break;
		}
	}
	return ret;
}

static int mb862xx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
			int num)
{
	struct mb862xxfb_par *par = adap->algo_data;
	struct i2c_msg *m;
	int addr;
	int i = 0, err = 0;

	dev_dbg(par->dev, "%s: %d msgs\n", __func__, num);

	for (i = 0; i < num; i++) {
		m = &msgs[i];
		if (!m->len) {
			dev_dbg(par->dev, "%s: null msgs\n", __func__);
			continue;
		}
		addr = m->addr;
		if (m->flags & I2C_M_RD)
			addr |= 1;

		err = mb862xx_i2c_do_address(adap, addr);
		if (err < 0)
			break;
		if (m->flags & I2C_M_RD)
			err = mb862xx_i2c_read(adap, m);
		else
			err = mb862xx_i2c_write(adap, m);
	}

	if (i)
		mb862xx_i2c_stop(adap);

	return (err < 0) ? err : i;
}

static u32 mb862xx_func(struct i2c_adapter *adap)
{
	return I2C_FUNC_SMBUS_BYTE_DATA;
}

static const struct i2c_algorithm mb862xx_algo = {
	.master_xfer	= mb862xx_xfer,
	.functionality	= mb862xx_func,
};

static struct i2c_adapter mb862xx_i2c_adapter = {
	.name		= "MB862xx I2C adapter",
	.algo		= &mb862xx_algo,
	.owner		= THIS_MODULE,
};

int mb862xx_i2c_init(struct mb862xxfb_par *par)
{
	int ret;

	mb862xx_i2c_adapter.algo_data = par;
	par->adap = &mb862xx_i2c_adapter;

	ret = i2c_add_adapter(par->adap);
	if (ret < 0) {
		dev_err(par->dev, "failed to add %s\n",
			mb862xx_i2c_adapter.name);
	}
	return ret;
}

void mb862xx_i2c_exit(struct mb862xxfb_par *par)
{
	if (par->adap) {
		i2c_del_adapter(par->adap);
		par->adap = NULL;
	}
}
