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

📄 eeprom.c

📁 linux plx9054芯片驱动程序 设备为一块只写PMC板
💻 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 + -