123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- /*
- * (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;
- }
- /*----------------------------------------------------------------------------*/
|