📄 eeprom.c
字号:
/******************************************************************************
*
* File Name:
*
* Eeprom.c
*
* Description:
*
* This file contains 9000-series EEPROM support functions.
*
******************************************************************************/
#include <asm/io.h>
#include "myvalues.h"
/**********************************************
* Definitions
**********************************************/
// EEPROM Control register offset
#if !defined(REG_EEPROM_CTRL)
#error ERROR: 'REG_EEPROM_CTRL' not defined
#endif
/******************************************************************************
*
* Function : EepromClock
*
* Description: Sends the clocking sequence to the EEPROM
*
******************************************************************************/
void
EepromClock()
{
S8 i;
U32 RegisterValue;
RegisterValue = PLX_REG_READ(REG_EEPROM_CTRL);
// Set EEPROM clock High
PLX_REG_WRITE(RegisterValue | (1 << 24));
// Need a small delay, perform dummy register reads
for (i=0; i<20; i++)
{
RegisterValue =PLX_REG_READ( REG_EEPROM_CTRL );
}
// Set EEPROM clock Low
PLX_REG_WRITE( RegisterValue & ~(1 << 24) );
}
/******************************************************************************
*
* Function : EepromSendCommand
*
* Description: Sends a Command to the EEPROM
*
******************************************************************************/
void
EepromSendCommand( U32 EepromCommand, U8 DataLengthInBits )
{
signed char BitPos;
U32 RegisterValue;
RegisterValue =
PLX_REG_READ(REG_EEPROM_CTRL);
printk(KERN_ALERT "register value =0x%x \n",RegisterValue);
// Clear all EEPROM bits
RegisterValue &= ~(0xF << 24);
// Toggle EEPROM's Chip select to get it out of Shift Register Mode
PLX_REG_WRITE( RegisterValue);
// Enable EEPROM Chip Select
RegisterValue |= (1 << 25);
PLX_REG_WRITE(RegisterValue);
// Send EEPROM command - one bit at a time
// for (BitPos = (S8)(11-1); BitPos >= 0; BitPos--) for (BitPos = 10; BitPos >= 0; BitPos--)
{// printk(KERN_ALERT "register value =0x%x \n",RegisterValue);
// Check if current bit is 0 or 1
if (EepromCommand & (1 << BitPos))
PLX_REG_WRITE(RegisterValue | (1 << 26));
else
PLX_REG_WRITE(RegisterValue);
EepromClock();
} printk(KERN_ALERT "send command over \n");
}
/******************************************************************************
*
* Function : EepromReadByOffset
*
* Description: Read a value from the EEPROM at a specified offset
*
******************************************************************************/
unsigned long
EepromRead( U16 offset)
{
S8 BitPos;
S8 CommandShift;
S8 CommandLength;
U16 count;
U32 RegisterValue; U32 *pValue=0,value; pValue=&value;
// case Eeprom93CS66:
CommandShift = 2;
CommandLength = EE66_CMD_LEN;
printk(KERN_ALERT "eeprom read \n");
// Send EEPROM read command and offset to EEPROM
EepromSendCommand(
(EE_READ << CommandShift) | (offset / 2),
CommandLength
);
printk(KERN_ALERT "return eeprom read! \n");
/*****************************************************
* Note: The EEPROM write ouput bit (26) is set here
* because it is required before EEPROM read
* operations on the 9054. It does not affect
* behavior of non-9054 chips.
*
* The EEDO Input enable bit (31) is required for
* some chips. Since it is a reserved bit in older
* chips, there is no harm in setting it for all.
****************************************************/
// Set EEPROM write output bit
RegisterValue =
PLX_REG_READ(REG_EEPROM_CTRL);
// Set EEDO Input enable for some PLX chips
RegisterValue |= (1 << 31);
PLX_REG_WRITE( RegisterValue | (1 << 26)
);
// Get 32-bit value from EEPROM - one bit at a time
for (BitPos = 0; BitPos < 32; BitPos++)
{
// Trigger the EEPROM clock
EepromClock();
/*****************************************************
* Note: After the EEPROM clock, a delay is sometimes
* needed to let the data bit propagate from the
* EEPROM to the PLX chip. If a sleep mechanism
* is used, the result is an extremely slow EEPROM
* access since the delay resolution is large and
* is required for every data bit read.
*
* Rather than using the standard sleep mechanism,
* the code, instead, reads the PLX register
* multiple times. This is harmless and provides
* enough delay for the EEPROM data to propagate.
****************************************************/
for (count=0; count < 20; count++)
{
// Get the result bit
RegisterValue =
PLX_REG_READ(REG_EEPROM_CTRL);
}
// Get bit value and shift into result
if (RegisterValue & (1 << 27))
{
*pValue = (*pValue << 1) | 1;
}
else
{
*pValue = (*pValue << 1);
}
}
// Clear EEDO Input enable for some PLX chips
RegisterValue &= ~(1 << 31);
// Clear Chip Select and all other EEPROM bits
PLX_REG_WRITE(
RegisterValue & ~(0xF << 24)
); return *pValue;
}
/******************************************************************************
*
* Function : EepromWrite
*
* Description: Write a value to the EEPROM at a specified offset
*
******************************************************************************/
void
EepromWrite(U32 value ,U16 offset)
{
S8 i;
signed char BitPos;
S8 CommandShift;
S8 CommandLength;
U16 EepromValue;
S32 Timeout;
U32 RegisterValue;
// case Eeprom93CS66:
CommandShift = 2;
CommandLength = EE66_CMD_LEN;
// Write EEPROM 16-bits at a time
for (i=0; i<2; i++)
{
// Set 16-bit value to write
if (i == 0)
{
EepromValue = (U16)(value >> 16);
}
else
{
EepromValue = (U16)value;
// Update offset
offset = offset + sizeof(U16);
}
// printk(KERN_ALERT "\n 1 \n");
// Send Write_Enable command to EEPROM
EepromSendCommand( (EE_WREN << CommandShift),CommandLength );
// printk(KERN_ALERT "\n 2 \n");
// Send EEPROM Write command and offset to EEPROM
EepromSendCommand( (EE_WRITE << CommandShift) | (offset / 2),CommandLength );
// printk(KERN_ALERT "\n 3 \n");
RegisterValue =
PLX_REG_READ( REG_EEPROM_CTRL );
// Clear all EEPROM bits
RegisterValue &= ~(0xF << 24);
// Make sure EEDO Input is disabled for some PLX chips
RegisterValue &= ~(1 << 31);
// Enable EEPROM Chip Select
RegisterValue |= (1 << 25); // printk(KERN_ALERT "\n 4 \n");
// Write 16-bit value to EEPROM - one bit at a time
for (BitPos = 15; BitPos >= 0; BitPos--)
{
// Get bit value and shift into result
if (EepromValue & (1 << BitPos))
{
PLX_REG_WRITE( RegisterValue | (1 << 26) );
}
else
{
PLX_REG_WRITE( RegisterValue );
}
// Trigger the EEPROM clock
EepromClock(); // printk(KERN_ALERT "\n 5 \n");
}
// Deselect Chip
PLX_REG_WRITE( RegisterValue & ~(1 << 25) );
// Re-select Chip
PLX_REG_WRITE( RegisterValue | (1 << 25) );
/*****************************************************
* Note: After the clocking in the last data bit, a
* delay is needed to let the EEPROM internally
* complete the write operation. If a sleep
* mechanism is used, the result is an extremely
* slow EEPROM access since the delay resolution
* is too large.
*
* Rather than using the standard sleep mechanism,
* the code, instead, reads the PLX register
* multiple times. This is harmless and provides
* enough delay for the EEPROM write to complete.
****************************************************/
// A small delay is needed to let EEPROM complete
Timeout = 0;
do
{
RegisterValue =
PLX_REG_READ( REG_EEPROM_CTRL);
Timeout++;
}
while (((RegisterValue & (1 << 27)) == 0) && (Timeout < 20000));
// Send Write_Disable command to EEPROM
EepromSendCommand( EE_WDS << CommandShift,CommandLength);
// printk(KERN_ALERT "\n 7 \n");
// Clear Chip Select and all other EEPROM bits
PLX_REG_WRITE(RegisterValue & ~(0xF << 24));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -