⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpc107_i2c.c

📁 gumstiz u-boot loader in linux
💻 C
字号:
/* * (C) Copyright 2002 ELTEC Elektronik AG * Frank Gottschling <fgottschling@eltec.de> * * See file CREDITS for list of people who contributed to this * project. * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA *//* 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;}/*----------------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -