/*
 * (C) Copyright 2002 ELTEC Elektronik AG
 * Frank Gottschling <fgottschling@eltec.de>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/* includes */
#include <common.h>
#include "srom.h"

/* locals */
static unsigned long mpc107_eumb_addr = 0;

/*----------------------------------------------------------------------------*/

/*
 * calculate checksum for ELTEC revision srom
 */
unsigned long el_srom_checksum (ptr, size)
register unsigned char *ptr;
unsigned long size;
{
    u_long f, accu = 0;
    u_int  i;
    u_char byte;

    for (; size; size--)
    {
	byte = *ptr++;
	for (i = 8; i; i--)
	{
	    f =  ((byte & 1) ^ (accu & 1)) ? 0x84083001 : 0;
	    accu >>= 1; accu ^= f;
	    byte >>= 1;
	}
    }
    return(accu);
}

/*----------------------------------------------------------------------------*/

static int mpc107_i2c_wait ( unsigned long timeout )
{
    unsigned long x;

    while (((x = in32r(MPC107_I2CSR)) & 0x82) != 0x82)
    {
	if (!timeout--)
	    return -1;
    }

    if (x & 0x10)
    {
	return -1;
    }
    out32r(MPC107_I2CSR, 0);

    return 0;
}

/*----------------------------------------------------------------------------*/

static int mpc107_i2c_wait_idle ( unsigned long timeout )
{
    while (in32r(MPC107_I2CSR) & 0x20)
    {
	if (!timeout--)
	    return -1;
    }
    return 0;
}


/*----------------------------------------------------------------------------*/

int mpc107_i2c_read_byte (
    unsigned char device,
    unsigned char block,
    unsigned char offset )
{
    unsigned long timeout = MPC107_I2C_TIMEOUT;
    int data;

    if (!mpc107_eumb_addr)
	return -6;

    mpc107_i2c_wait_idle (timeout);

    /* Start with MEN */
    out32r(MPC107_I2CCR, 0x80);

    /* Start as master */
    out32r(MPC107_I2CCR, 0xB0);
    out32r(MPC107_I2CDR, (0xA0 | device | block));

    if (mpc107_i2c_wait(timeout) < 0)
    {
	printf("mpc107_i2c_read Error 1\n");
	return -2;
    }

    if (in32r(MPC107_I2CSR)&0x1)
    {
	/* Generate STOP condition; device busy or not existing */
	out32r(MPC107_I2CCR, 0x80);
	return -1;
    }

    /* Data address */
    out32r(MPC107_I2CDR, offset);

    if (mpc107_i2c_wait(timeout) < 0)
    {
	printf("mpc107_i2c_read Error 2\n");
	return -3;
    }

    /* Switch to read - restart */
    out32r(MPC107_I2CCR, 0xB4);
    out32r(MPC107_I2CDR, (0xA1 | device | block));

    if (mpc107_i2c_wait(timeout) < 0)
    {
	printf("mpc107_i2c_read Error 3\n");
	return -4;
    }

    out32r(MPC107_I2CCR, 0xA8); /* no ACK */
    in32r(MPC107_I2CDR);

    if (mpc107_i2c_wait(timeout) < 0)
    {
	printf("mpc107_i2c_read Error 4\n");
	return -5;
    }
    /* Generate STOP condition */
    out32r(MPC107_I2CCR, 0x88);

    /* read */
    data = in32r(MPC107_I2CDR);

    return (data);
}

/*----------------------------------------------------------------------------*/

int mpc107_i2c_write_byte (
    unsigned char device,
    unsigned char block,
    unsigned char offset,
    unsigned char val )
{

    unsigned long timeout = MPC107_I2C_TIMEOUT;

    if (!mpc107_eumb_addr)
	return -6;

    mpc107_i2c_wait_idle(timeout);

    /* Start with MEN */
    out32r(MPC107_I2CCR, 0x80);

    /* Start as master */
    out32r(MPC107_I2CCR, 0xB0);
    out32r(MPC107_I2CDR, (0xA0 | device | block));

    if (mpc107_i2c_wait(timeout) < 0)
    {
	printf("mpc107_i2c_write Error 1\n");
	return -1;
    }

    /* Data address */
    out32r(MPC107_I2CDR, offset);

    if (mpc107_i2c_wait(timeout) < 0)
    {
	printf("mpc107_i2c_write Error 2\n");
	return -1;
    }

    /* Write */
    out32r(MPC107_I2CDR, val);
    if (mpc107_i2c_wait(timeout) < 0)
    {
	printf("mpc107_i2c_write Error 3\n");
	return -1;
    }

    /* Generate Stop Condition */
    out32r(MPC107_I2CCR, 0x80);

    /* Return ACK or no ACK */
    return (in32r(MPC107_I2CSR) & 0x01);
}

/*----------------------------------------------------------------------------*/

int mpc107_srom_load (
    unsigned char addr,
    unsigned char *pBuf,
    int          cnt,
    unsigned char device,
    unsigned char block )
{
    register int i;
    int val;
    int timeout;

    for (i = 0; i < cnt; i++)
    {
	timeout=100;
	do
	{
	    val = mpc107_i2c_read_byte (device, block, addr);
	    if (val < -1)
	    {
	    printf("i2c_read_error %d at dev %x block %x addr %x\n",
		   val, device, block, addr);
	    return -1;
	    }
	    else if (timeout==0)
	    {
		printf ("i2c_read_error: timeout at dev %x block %x addr %x\n",
			device, block, addr);
		return -1;
	    }
	    timeout--;
	} while (val == -1); /* if no ack: try again! */

	*pBuf++ = (unsigned char)val;
	addr++;

	if ((addr == 0) && (i != cnt-1))    /* is it the same block ? */
	{
	    if (block == FIRST_BLOCK)
		block = SECOND_BLOCK;
	    else
	    {
		printf ("ic2_read_error: read beyond 2. block !\n");
		return -1;
	    }
	}
    }
    udelay(100000);
    return (cnt);
}

/*----------------------------------------------------------------------------*/

int mpc107_srom_store (
    unsigned char addr,
    unsigned char *pBuf,
    int          cnt,
    unsigned char device,
    unsigned char block )
{
    register int i;

    for (i = 0; i < cnt; i++)
    {
	while (mpc107_i2c_write_byte (device,block,addr,*pBuf) == 1);
	addr++;
	pBuf++;

	if ((addr == 0) && (i != cnt-1))     /* is it the same block ? */
	{
	    if (block == FIRST_BLOCK)
		block = SECOND_BLOCK;
	    else
	    {
		printf ("ic2_write_error: write beyond 2. block !\n");
		return -1;
	    }
	}
    }
    udelay(100000);
    return(cnt);
}

/*----------------------------------------------------------------------------*/

int mpc107_i2c_init ( unsigned long eumb_addr, unsigned long divider )
{
    unsigned long x;

    if (eumb_addr)
	mpc107_eumb_addr = eumb_addr;
    else
	return -1;

    /* Set I2C clock */
    x = in32r(MPC107_I2CFDR) & 0xffffff00;
    out32r(MPC107_I2CFDR, (x | divider));

    /* Clear arbitration */
    out32r(MPC107_I2CSR, 0);

    return mpc107_eumb_addr;
}

/*----------------------------------------------------------------------------*/
