/*
 * 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 <linux/export.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;
	}
}
