aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/drivers/addi-data/addi_eeprom.c')
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_eeprom.c1367
1 files changed, 285 insertions, 1082 deletions
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
index 3a9339b92610..5124ac9f1818 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
+++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
@@ -1,1162 +1,365 @@
-/**
-@verbatim
-
-Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
-
- ADDI-DATA GmbH
- Dieselstrasse 3
- D-77833 Ottersweier
- Tel: +19(0)7223/9493-0
- Fax: +49(0)7223/9493-92
- http://www.addi-data.com
- info@addi-data.com
-
-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
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
-@endverbatim
-*/
/*
-
- +-----------------------------------------------------------------------+
- | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
- +-----------------------------------------------------------------------+
- | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
- | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
- +-----------------------------------------------------------------------+
- | Project : ADDI DATA | Compiler : GCC |
- | Modulname : addi_eeprom.c | Version : 2.96 |
- +-------------------------------+---------------------------------------+
- | Project manager: Eric Stolz | Date : 02/12/2002 |
- +-----------------------------------------------------------------------+
- | Description : ADDI EEPROM Module |
- +-----------------------------------------------------------------------+
- | UPDATE'S |
- +-----------------------------------------------------------------------+
- | Date | Author | Description of updates |
- +----------+-----------+------------------------------------------------+
- | | | |
- | | | |
- +----------+-----------+------------------------------------------------+
-*/
-
-#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */
-#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */
-#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */
-#define EE76_CMD_LEN 13 /* bits in instructions */
-#define EE_READ 0x0180 /* 01 1000 0000 read instruction */
-
-#define EEPROM_DIGITALINPUT 0
-#define EEPROM_DIGITALOUTPUT 1
-#define EEPROM_ANALOGINPUT 2
-#define EEPROM_ANALOGOUTPUT 3
-#define EEPROM_TIMER 4
-#define EEPROM_WATCHDOG 5
+ * addi_eeprom.c - ADDI EEPROM Module
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ * Project manager: Eric Stolz
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data.com
+ * info@addi-data.com
+ *
+ * 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
+ *
+ * You should also find the complete GPL in the COPYING file accompanying
+ * this source code.
+ */
+
+#define NVRAM_USER_DATA_START 0x100
+
+#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */
+#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */
+#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */
+
+#define EE93C76_CLK_BIT (1 << 0)
+#define EE93C76_CS_BIT (1 << 1)
+#define EE93C76_DOUT_BIT (1 << 2)
+#define EE93C76_DIN_BIT (1 << 3)
+#define EE93C76_READ_CMD (0x0180 << 4)
+#define EE93C76_CMD_LEN 13
+
+#define EEPROM_DIGITALINPUT 0
+#define EEPROM_DIGITALOUTPUT 1
+#define EEPROM_ANALOGINPUT 2
+#define EEPROM_ANALOGOUTPUT 3
+#define EEPROM_TIMER 4
+#define EEPROM_WATCHDOG 5
#define EEPROM_TIMER_WATCHDOG_COUNTER 10
-struct str_Functionality {
- unsigned char b_Type;
- unsigned short w_Address;
-};
-
-struct str_MainHeader {
- unsigned short w_HeaderSize;
- unsigned char b_Nfunctions;
- struct str_Functionality s_Functions[7];
-};
-
-struct str_DigitalInputHeader {
- unsigned short w_Nchannel;
- unsigned char b_Interruptible;
- unsigned short w_NinterruptLogic;
-};
-
-struct str_DigitalOutputHeader {
-
- unsigned short w_Nchannel;
-};
-
-
-/* used for timer as well as watchdog */
-
-struct str_TimerDetails {
-
- unsigned short w_HeaderSize;
- unsigned char b_Resolution;
- unsigned char b_Mode; /* in case of Watchdog it is functionality */
- unsigned short w_MinTiming;
- unsigned char b_TimeBase;
-};
-
-struct str_TimerMainHeader {
-
-
- unsigned short w_Ntimer;
- struct str_TimerDetails s_TimerDetails[4]; /* supports 4 timers */
-};
-
-
-struct str_AnalogOutputHeader {
- unsigned short w_Nchannel;
- unsigned char b_Resolution;
-};
-
-struct str_AnalogInputHeader {
- unsigned short w_Nchannel;
- unsigned short w_MinConvertTiming;
- unsigned short w_MinDelayTiming;
- unsigned char b_HasDma;
- unsigned char b_Resolution;
-};
-
-
- /*****************************************/
- /* Read Header Functions */
- /*****************************************/
-
-int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, struct comedi_device *dev);
-
-int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_DigitalInputHeader *s_Header);
-
-int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_DigitalOutputHeader *s_Header);
-
-int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_TimerMainHeader *s_Header);
-
-int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_AnalogOutputHeader *s_Header);
-
-int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_AnalogInputHeader *s_Header);
-
- /******************************************/
- /* Eeprom Specific Functions */
- /******************************************/
-unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
- unsigned short w_EepromStartAddress);
-void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress);
-void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue);
-void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress);
-void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand,
- unsigned char b_DataLengthInBits);
-void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value);
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : unsigned short w_EepromReadWord |
-| (unsigned short w_PCIBoardEepromAddress, |
-| char * pc_PCIChipInformation, |
-| unsigned short w_EepromStartAddress) |
-+----------------------------------------------------------------------------+
-| Task : Read from eepromn a word |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| unsigned short w_EepromStartAddress : Selected eeprom address |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : Read word value from eeprom |
-+----------------------------------------------------------------------------+
-*/
-
-unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
- unsigned short w_EepromStartAddress)
+static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val)
{
-
- unsigned char b_Counter = 0;
-
- unsigned char b_ReadByte = 0;
-
- unsigned char b_ReadLowByte = 0;
-
- unsigned char b_ReadHighByte = 0;
-
- unsigned char b_SelectedAddressLow = 0;
-
- unsigned char b_SelectedAddressHigh = 0;
-
- unsigned short w_ReadWord = 0;
-
- /**************************/
-
- /* Test the PCI chip type */
-
- /**************************/
-
- if ((!strcmp(pc_PCIChipInformation, "S5920")) ||
- (!strcmp(pc_PCIChipInformation, "S5933")))
- {
-
- for (b_Counter = 0; b_Counter < 2; b_Counter++)
- {
-
- b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; /* Read the low 8 bit part */
-
- b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; /* Read the high 8 bit part */
-
- /************************************/
-
- /* Select the load low address mode */
-
- /************************************/
-
- outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /************************/
-
- /* Load the low address */
-
- /************************/
-
- outb(b_SelectedAddressLow,
- w_PCIBoardEepromAddress + 0x3E);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /*************************************/
-
- /* Select the load high address mode */
-
- /*************************************/
-
- outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /*************************/
-
- /* Load the high address */
-
- /*************************/
-
- outb(b_SelectedAddressHigh,
- w_PCIBoardEepromAddress + 0x3E);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /************************/
-
- /* Select the READ mode */
-
- /************************/
-
- outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /*****************************/
-
- /* Read data into the EEPROM */
-
- /*****************************/
-
- b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E);
-
- /****************/
-
- /* Wait on busy */
-
- /****************/
-
- v_EepromWaitBusy(w_PCIBoardEepromAddress);
-
- /*********************************/
-
- /* Select the upper address part */
-
- /*********************************/
-
- if (b_Counter == 0)
- {
-
- b_ReadLowByte = b_ReadByte;
-
- } /* if(b_Counter==0) */
-
- else
- {
-
- b_ReadHighByte = b_ReadByte;
-
- } /* if(b_Counter==0) */
-
- } /* for (b_Counter=0; b_Counter<2; b_Counter++) */
-
- w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256));
-
- } /* end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) */
-
- if (!strcmp(pc_PCIChipInformation, "93C76"))
- {
-
- /*************************************/
-
- /* Read 16 bit from the EEPROM 93C76 */
-
- /*************************************/
-
- v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress,
- &w_ReadWord);
-
- }
-
- return w_ReadWord;
-
-}
-
-/*
-
-+----------------------------------------------------------------------------+
-
-| Function Name : void v_EepromWaitBusy |
-
-| (unsigned short w_PCIBoardEepromAddress) |
-
-+----------------------------------------------------------------------------+
-
-| Task : Wait the busy flag from PCI controller |
-
-+----------------------------------------------------------------------------+
-
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom base address |
-
-+----------------------------------------------------------------------------+
-
-| Output Parameters : - |
-
-+----------------------------------------------------------------------------+
-
-| Return Value : - |
-
-+----------------------------------------------------------------------------+
-
-*/
-
-void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress)
-{
-
- unsigned char b_EepromBusy = 0;
-
- do
- {
-
- /*************/
-
- /* IMPORTANT */
-
- /*************/
-
- /************************************************************************/
-
- /* An error has been written in the AMCC 5933 book at the page B-13 */
-
- /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */
-
- /* the operator register is AMCC_OP_REG_MCSR+3 */
-
- /* unsigned short read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */
-
- /* unsigned int read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */
-
- /************************************************************************/
-
- b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F);
- b_EepromBusy = b_EepromBusy & 0x80;
-
- } while (b_EepromBusy == 0x80);
-
-}
-
-/*
-
-+---------------------------------------------------------------------------------+
-
-| Function Name : void v_EepromClock76(unsigned int dw_Address, |
-
-| unsigned int dw_RegisterValue) |
-
-+---------------------------------------------------------------------------------+
-
-| Task : This function sends the clocking sequence to the EEPROM. |
-
-+---------------------------------------------------------------------------------+
-
-| Input Parameters : unsigned int dw_Address : PCI eeprom base address |
-
-| unsigned int dw_RegisterValue : PCI eeprom register value to write.|
-
-+---------------------------------------------------------------------------------+
-
-| Output Parameters : - |
-
-+---------------------------------------------------------------------------------+
-
-| Return Value : - |
-
-+---------------------------------------------------------------------------------+
-
-*/
-
-void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue)
-{
-
- /************************/
-
- /* Set EEPROM clock Low */
-
- /************************/
-
- outl(dw_RegisterValue & 0x6, dw_Address);
-
- /***************/
-
- /* Wait 0.1 ms */
-
- /***************/
-
+ outl(val & ~EE93C76_CLK_BIT, iobase);
udelay(100);
- /*************************/
-
- /* Set EEPROM clock High */
-
- /*************************/
-
- outl(dw_RegisterValue | 0x1, dw_Address);
-
- /***************/
-
- /* Wait 0.1 ms */
-
- /***************/
-
+ outl(val | EE93C76_CLK_BIT, iobase);
udelay(100);
-
}
-/*
-
-+---------------------------------------------------------------------------------+
-
-| Function Name : void v_EepromSendCommand76(unsigned int dw_Address, |
-
-| unsigned int dw_EepromCommand, |
-
-| unsigned char b_DataLengthInBits) |
-
-+---------------------------------------------------------------------------------+
-
-| Task : This function sends a Command to the EEPROM 93C76. |
-
-+---------------------------------------------------------------------------------+
-
-| Input Parameters : unsigned int dw_Address : PCI eeprom base address |
-
-| unsigned int dw_EepromCommand : PCI eeprom command to write. |
-
-| unsigned char b_DataLengthInBits : PCI eeprom command data length. |
-
-+---------------------------------------------------------------------------------+
-
-| Output Parameters : - |
-
-+---------------------------------------------------------------------------------+
-
-| Return Value : - |
-
-+---------------------------------------------------------------------------------+
-
-*/
-
-void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand,
- unsigned char b_DataLengthInBits)
+static unsigned int addi_eeprom_cmd_93c76(unsigned long iobase,
+ unsigned int cmd,
+ unsigned char len)
{
-
- char c_BitPos = 0;
-
- unsigned int dw_RegisterValue = 0;
-
- /*****************************/
-
- /* Enable EEPROM Chip Select */
-
- /*****************************/
-
- dw_RegisterValue = 0x2;
-
- /********************************************************************/
+ unsigned int val = EE93C76_CS_BIT;
+ int i;
/* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
-
- /********************************************************************/
-
- outl(dw_RegisterValue, dw_Address);
-
- /***************/
-
- /* Wait 0.1 ms */
-
- /***************/
-
+ outl(val, iobase);
udelay(100);
- /*******************************************/
-
/* Send EEPROM command - one bit at a time */
-
- /*******************************************/
-
- for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--)
- {
-
- /**********************************/
-
- /* Check if current bit is 0 or 1 */
-
- /**********************************/
-
- if (dw_EepromCommand & (1 << c_BitPos))
- {
-
- /***********/
-
- /* Write 1 */
-
- /***********/
-
- dw_RegisterValue = dw_RegisterValue | 0x4;
-
- }
-
+ for (i = (len - 1); i >= 0; i--) {
+ if (cmd & (1 << i))
+ val |= EE93C76_DOUT_BIT;
else
- {
-
- /***********/
-
- /* Write 0 */
-
- /***********/
-
- dw_RegisterValue = dw_RegisterValue & 0x3;
-
- }
-
- /*********************/
+ val &= ~EE93C76_DOUT_BIT;
/* Write the command */
-
- /*********************/
-
- outl(dw_RegisterValue, dw_Address);
-
- /***************/
-
- /* Wait 0.1 ms */
-
- /***************/
-
+ outl(val, iobase);
udelay(100);
- /****************************/
-
- /* Trigger the EEPROM clock */
-
- /****************************/
-
- v_EepromClock76(dw_Address, dw_RegisterValue);
-
+ addi_eeprom_clk_93c76(iobase, val);
}
-
+ return val;
}
-/*
-
-+---------------------------------------------------------------------------------+
-
-| Function Name : void v_EepromCs76Read(unsigned int dw_Address, |
-
-| unsigned short w_offset, |
-
-| unsigned short * pw_Value) |
-
-+---------------------------------------------------------------------------------+
-
-| Task : This function read a value from the EEPROM 93C76. |
-
-+---------------------------------------------------------------------------------+
-
-| Input Parameters : unsigned int dw_Address : PCI eeprom base address |
-
-| unsigned short w_offset : Offset of the address to read |
-
-| unsigned short * pw_Value : PCI eeprom 16 bit read value. |
-
-+---------------------------------------------------------------------------------+
-
-| Output Parameters : - |
-
-+---------------------------------------------------------------------------------+
-
-| Return Value : - |
-
-+---------------------------------------------------------------------------------+
-
-*/
-
-void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value)
+static unsigned short addi_eeprom_readw_93c76(unsigned long iobase,
+ unsigned short addr)
{
-
- char c_BitPos = 0;
-
- unsigned int dw_RegisterValue = 0;
-
- unsigned int dw_RegisterValueRead = 0;
-
- /*************************************************/
+ unsigned short val = 0;
+ unsigned int cmd;
+ unsigned int tmp;
+ int i;
/* Send EEPROM read command and offset to EEPROM */
-
- /*************************************************/
-
- v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2),
- EE76_CMD_LEN);
-
- /*******************************/
-
- /* Get the last register value */
-
- /*******************************/
-
- dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2;
-
- /*****************************/
-
- /* Set the 16-bit value of 0 */
-
- /*****************************/
-
- *pw_Value = 0;
-
- /************************/
+ cmd = EE93C76_READ_CMD | (addr / 2);
+ cmd = addi_eeprom_cmd_93c76(iobase, cmd, EE93C76_CMD_LEN);
/* Get the 16-bit value */
+ for (i = 0; i < 16; i++) {
+ addi_eeprom_clk_93c76(iobase, cmd);
- /************************/
-
- for (c_BitPos = 0; c_BitPos < 16; c_BitPos++)
- {
-
- /****************************/
-
- /* Trigger the EEPROM clock */
-
- /****************************/
-
- v_EepromClock76(dw_Address, dw_RegisterValue);
-
- /**********************/
-
- /* Get the result bit */
-
- /**********************/
-
- dw_RegisterValueRead = inl(dw_Address);
-
- /***************/
-
- /* Wait 0.1 ms */
-
- /***************/
-
+ tmp = inl(iobase);
udelay(100);
- /***************************************/
-
- /* Get bit value and shift into result */
-
- /***************************************/
-
- if (dw_RegisterValueRead & 0x8)
- {
-
- /**********/
+ val <<= 1;
+ if (tmp & EE93C76_DIN_BIT)
+ val |= 0x1;
+ }
- /* Read 1 */
+ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+ outl(0, iobase);
+ udelay(100);
- /**********/
+ return val;
+}
- *pw_Value = (*pw_Value << 1) | 0x1;
+static void addi_eeprom_nvram_wait(unsigned long iobase)
+{
+ unsigned char val;
- }
+ do {
+ val = inb(iobase + AMCC_OP_REG_MCSR_NVCMD);
+ } while (val & 0x80);
+}
+static unsigned short addi_eeprom_readw_nvram(unsigned long iobase,
+ unsigned short addr)
+{
+ unsigned short val = 0;
+ unsigned char tmp;
+ unsigned char i;
+
+ for (i = 0; i < 2; i++) {
+ /* Load the low 8 bit address */
+ outb(NVCMD_LOAD_LOW, iobase + AMCC_OP_REG_MCSR_NVCMD);
+ addi_eeprom_nvram_wait(iobase);
+ outb((addr + i) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
+ addi_eeprom_nvram_wait(iobase);
+
+ /* Load the high 8 bit address */
+ outb(NVCMD_LOAD_HIGH, iobase + AMCC_OP_REG_MCSR_NVCMD);
+ addi_eeprom_nvram_wait(iobase);
+ outb(((addr + i) >> 8) & 0xff,
+ iobase + AMCC_OP_REG_MCSR_NVDATA);
+ addi_eeprom_nvram_wait(iobase);
+
+ /* Read the eeprom data byte */
+ outb(NVCMD_BEGIN_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
+ addi_eeprom_nvram_wait(iobase);
+ tmp = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
+ addi_eeprom_nvram_wait(iobase);
+
+ if (i == 0)
+ val |= tmp;
else
- {
-
- /**********/
-
- /* Read 0 */
+ val |= (tmp << 8);
+ }
- /**********/
+ return val;
+}
- *pw_Value = (*pw_Value << 1);
+static unsigned short addi_eeprom_readw(unsigned long iobase,
+ char *type,
+ unsigned short addr)
+{
+ unsigned short val = 0;
- }
+ /* Add the offset to the start of the user data */
+ addr += NVRAM_USER_DATA_START;
- }
+ if (!strcmp(type, "S5920") || !strcmp(type, "S5933"))
+ val = addi_eeprom_readw_nvram(iobase, addr);
- /*************************/
+ if (!strcmp(type, "93C76"))
+ val = addi_eeprom_readw_93c76(iobase, addr);
- /* Clear all EEPROM bits */
+ return val;
+}
- /*************************/
+static void addi_eeprom_read_di_info(struct comedi_device *dev,
+ unsigned long iobase,
+ unsigned short addr)
+{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
+ char *type = this_board->pc_EepromChip;
+ unsigned short tmp;
- dw_RegisterValue = 0x0;
+ /* Number of channels */
+ tmp = addi_eeprom_readw(iobase, type, addr + 6);
+ devpriv->s_EeParameters.i_NbrDiChannel = tmp;
- /********************************************************************/
+ /* Interruptible or not */
+ tmp = addi_eeprom_readw(iobase, type, addr + 8);
+ tmp = (tmp >> 7) & 0x01;
- /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+ /* How many interruptible logic */
+ tmp = addi_eeprom_readw(iobase, type, addr + 10);
+}
- /********************************************************************/
+static void addi_eeprom_read_do_info(struct comedi_device *dev,
+ unsigned long iobase,
+ unsigned short addr)
+{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
+ char *type = this_board->pc_EepromChip;
+ unsigned short tmp;
- outl(dw_RegisterValue, dw_Address);
+ /* Number of channels */
+ tmp = addi_eeprom_readw(iobase, type, addr + 6);
+ devpriv->s_EeParameters.i_NbrDoChannel = tmp;
- /***************/
+ devpriv->s_EeParameters.i_DoMaxdata = 0xffffffff >> (32 - tmp);
+}
- /* Wait 0.1 ms */
+static void addi_eeprom_read_timer_info(struct comedi_device *dev,
+ unsigned long iobase,
+ unsigned short addr)
+{
+ struct addi_private *devpriv = dev->private;
+#if 0
+ const struct addi_board *this_board = comedi_board(dev);
+ char *type = this_board->pc_EepromChip;
+ unsigned short offset = 0;
+ unsigned short ntimers;
+ unsigned short tmp;
+ int i;
+
+ /* Number of Timers */
+ ntimers = addi_eeprom_readw(iobase, type, addr + 6);
+
+ /* Read header size */
+ for (i = 0; i < ntimers; i++) {
+ unsigned short size;
+ unsigned short res;
+ unsigned short mode;
+ unsigned short min_timing;
+ unsigned short timebase;
+
+ size = addi_eeprom_readw(iobase, type, addr + 8 + offset + 0);
+
+ /* Resolution / Mode */
+ tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 2);
+ res = (tmp >> 10) & 0x3f;
+ mode = (tmp >> 4) & 0x3f;
+
+ /* MinTiming / Timebase */
+ tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 4);
+ min_timing = (tmp >> 6) & 0x3ff;
+ Timebase = tmp & 0x3f;
+
+ offset += size;
+ }
+#endif
+ /* Timer subdevice present */
+ devpriv->s_EeParameters.i_Timer = 1;
+}
- /***************/
+static void addi_eeprom_read_ao_info(struct comedi_device *dev,
+ unsigned long iobase,
+ unsigned short addr)
+{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
+ char *type = this_board->pc_EepromChip;
+ unsigned short tmp;
+
+ /* No of channels for 1st hard component */
+ tmp = addi_eeprom_readw(iobase, type, addr + 10);
+ devpriv->s_EeParameters.i_NbrAoChannel = (tmp >> 4) & 0x3ff;
+
+ /* Resolution for 1st hard component */
+ tmp = addi_eeprom_readw(iobase, type, addr + 16);
+ tmp = (tmp >> 8) & 0xff;
+ devpriv->s_EeParameters.i_AoMaxdata = 0xfff >> (16 - tmp);
+}
- udelay(100);
+static void addi_eeprom_read_ai_info(struct comedi_device *dev,
+ unsigned long iobase,
+ unsigned short addr)
+{
+ const struct addi_board *this_board = comedi_board(dev);
+ struct addi_private *devpriv = dev->private;
+ char *type = this_board->pc_EepromChip;
+ unsigned short offset;
+ unsigned short tmp;
+
+ /* No of channels for 1st hard component */
+ tmp = addi_eeprom_readw(iobase, type, addr + 10);
+ devpriv->s_EeParameters.i_NbrAiChannel = (tmp >> 4) & 0x3ff;
+ if (!strcmp(this_board->pc_DriverName, "apci3200"))
+ devpriv->s_EeParameters.i_NbrAiChannel *= 4;
+
+ tmp = addi_eeprom_readw(iobase, type, addr + 16);
+ devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = tmp * 1000;
+
+ tmp = addi_eeprom_readw(iobase, type, addr + 30);
+ devpriv->s_EeParameters.ui_MinDelaytimeNs = tmp * 1000;
+
+ tmp = addi_eeprom_readw(iobase, type, addr + 20);
+ devpriv->s_EeParameters.i_Dma = (tmp >> 13) & 0x01;
+
+ tmp = addi_eeprom_readw(iobase, type, addr + 72) & 0xff;
+ if (tmp) { /* > 0 */
+ /* offset of first analog input single header */
+ offset = 74 + (2 * tmp) + (10 * (1 + (tmp / 16)));
+ } else { /* = 0 */
+ offset = 74;
+ }
+ /* Resolution */
+ tmp = addi_eeprom_readw(iobase, type, addr + offset + 2) & 0x1f;
+ devpriv->s_EeParameters.i_AiMaxdata = 0xffff >> (16 - tmp);
}
- /******************************************/
- /* EEPROM HEADER READ FUNCTIONS */
- /******************************************/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, |
-| char * pc_PCIChipInformation,struct comedi_device *dev) |
-+----------------------------------------------------------------------------+
-| Task : Read from eeprom Main Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| struct comedi_device *dev : comedi device structure |
-| pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-
-int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, struct comedi_device *dev)
+static void addi_eeprom_read_info(struct comedi_device *dev,
+ unsigned long iobase)
{
- unsigned short w_Temp, i, w_Count = 0;
- unsigned int ui_Temp;
- struct str_MainHeader s_MainHeader;
- struct str_DigitalInputHeader s_DigitalInputHeader;
- struct str_DigitalOutputHeader s_DigitalOutputHeader;
- /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */
- struct str_AnalogOutputHeader s_AnalogOutputHeader;
- struct str_AnalogInputHeader s_AnalogInputHeader;
-
- /* Read size */
- s_MainHeader.w_HeaderSize =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + 8);
-
- /* Read nbr of functionality */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + 10);
- s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF;
+ const struct addi_board *this_board = comedi_board(dev);
+ char *type = this_board->pc_EepromChip;
+ unsigned short size;
+ unsigned char nfuncs;
+ int i;
+
+ size = addi_eeprom_readw(iobase, type, 8);
+ nfuncs = addi_eeprom_readw(iobase, type, 10) & 0xff;
/* Read functionality details */
- for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
- /* Read Type */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + 12 + w_Count);
- s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F;
- w_Count = w_Count + 2;
- /* Read Address */
- s_MainHeader.s_Functions[i].w_Address =
- w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + 12 + w_Count);
- w_Count = w_Count + 2;
- }
+ for (i = 0; i < nfuncs; i++) {
+ unsigned short offset = i * 4;
+ unsigned short addr;
+ unsigned char func;
- /* Display main header info */
- for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
+ func = addi_eeprom_readw(iobase, type, 12 + offset) & 0x3f;
+ addr = addi_eeprom_readw(iobase, type, 14 + offset);
- switch (s_MainHeader.s_Functions[i].b_Type) {
+ switch (func) {
case EEPROM_DIGITALINPUT:
- i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- s_MainHeader.s_Functions[i].w_Address,
- &s_DigitalInputHeader);
- devpriv->s_EeParameters.i_NbrDiChannel =
- s_DigitalInputHeader.w_Nchannel;
+ addi_eeprom_read_di_info(dev, iobase, addr);
break;
case EEPROM_DIGITALOUTPUT:
- i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- s_MainHeader.s_Functions[i].w_Address,
- &s_DigitalOutputHeader);
- devpriv->s_EeParameters.i_NbrDoChannel =
- s_DigitalOutputHeader.w_Nchannel;
- ui_Temp = 0xffffffff;
- devpriv->s_EeParameters.i_DoMaxdata =
- ui_Temp >> (32 -
- devpriv->s_EeParameters.i_NbrDoChannel);
+ addi_eeprom_read_do_info(dev, iobase, addr);
break;
case EEPROM_ANALOGINPUT:
- i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- s_MainHeader.s_Functions[i].w_Address,
- &s_AnalogInputHeader);
- if (!(strcmp(this_board->pc_DriverName, "apci3200")))
- devpriv->s_EeParameters.i_NbrAiChannel =
- s_AnalogInputHeader.w_Nchannel * 4;
- else
- devpriv->s_EeParameters.i_NbrAiChannel =
- s_AnalogInputHeader.w_Nchannel;
- devpriv->s_EeParameters.i_Dma =
- s_AnalogInputHeader.b_HasDma;
- devpriv->s_EeParameters.ui_MinAcquisitiontimeNs =
- (unsigned int) s_AnalogInputHeader.w_MinConvertTiming *
- 1000;
- devpriv->s_EeParameters.ui_MinDelaytimeNs =
- (unsigned int) s_AnalogInputHeader.w_MinDelayTiming *
- 1000;
- ui_Temp = 0xffff;
- devpriv->s_EeParameters.i_AiMaxdata =
- ui_Temp >> (16 -
- s_AnalogInputHeader.b_Resolution);
+ addi_eeprom_read_ai_info(dev, iobase, addr);
break;
case EEPROM_ANALOGOUTPUT:
- i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- s_MainHeader.s_Functions[i].w_Address,
- &s_AnalogOutputHeader);
- devpriv->s_EeParameters.i_NbrAoChannel =
- s_AnalogOutputHeader.w_Nchannel;
- ui_Temp = 0xffff;
- devpriv->s_EeParameters.i_AoMaxdata =
- ui_Temp >> (16 -
- s_AnalogOutputHeader.b_Resolution);
+ addi_eeprom_read_ao_info(dev, iobase, addr);
break;
case EEPROM_TIMER:
- /* Timer subdevice present */
- devpriv->s_EeParameters.i_Timer = 1;
- break;
-
case EEPROM_WATCHDOG:
- /* Timer subdevice present */
- devpriv->s_EeParameters.i_Timer = 1;
- break;
-
case EEPROM_TIMER_WATCHDOG_COUNTER:
- /* Timer subdevice present */
- devpriv->s_EeParameters.i_Timer = 1;
+ addi_eeprom_read_timer_info(dev, iobase, addr);
break;
}
}
-
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadDigitalInputHeader(unsigned short |
-| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
-| unsigned short w_Address,struct str_DigitalInputHeader *s_Header) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Read Digital Input Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| struct str_DigitalInputHeader *s_Header: Digita Input Header |
-| Pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_DigitalInputHeader *s_Header)
-{
- unsigned short w_Temp;
-
- /* read nbr of channels */
- s_Header->w_Nchannel =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 6);
-
- /* interruptible or not */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + 8);
- s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01;
-
-/* How many interruptible logic */
- s_Header->w_NinterruptLogic =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 10);
-
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadDigitalOutputHeader(unsigned short |
-| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
-| unsigned short w_Address,struct str_DigitalOutputHeader *s_Header) |
-| |
-+----------------------------------------------------------------------------+
-| Task : Read Digital Output Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| struct str_DigitalOutputHeader *s_Header: Digital Output Header|
-| Pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_DigitalOutputHeader *s_Header)
-{
-/* Read Nbr channels */
- s_Header->w_Nchannel =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 6);
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, |
-| char *pc_PCIChipInformation,WORD w_Address, |
-| struct str_TimerMainHeader *s_Header) |
-+----------------------------------------------------------------------------+
-| Task : Read Timer or Watchdog Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| struct str_TimerMainHeader *s_Header: Timer Header |
-| Pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_TimerMainHeader *s_Header)
-{
-
- unsigned short i, w_Size = 0, w_Temp;
-
-/* Read No of Timer */
- s_Header->w_Ntimer =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 6);
-/* Read header size */
-
- for (i = 0; i < s_Header->w_Ntimer; i++) {
- s_Header->s_TimerDetails[i].w_HeaderSize =
- w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- 0x100 + w_Address + 8 + w_Size + 0);
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- 0x100 + w_Address + 8 + w_Size + 2);
-
- /* Read Resolution */
- s_Header->s_TimerDetails[i].b_Resolution =
- (unsigned char) (w_Temp >> 10) & 0x3F;
-
- /* Read Mode */
- s_Header->s_TimerDetails[i].b_Mode =
- (unsigned char) (w_Temp >> 4) & 0x3F;
-
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation,
- 0x100 + w_Address + 8 + w_Size + 4);
-
- /* Read MinTiming */
- s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF;
-
- /* Read Timebase */
- s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F;
- w_Size += s_Header->s_TimerDetails[i].w_HeaderSize;
- }
-
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadAnlogOutputHeader(unsigned short |
-| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
-| unsigned short w_Address,str_AnalogOutputHeader *s_Header) |
-+----------------------------------------------------------------------------+
-| Task : Read Nalog Output Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| str_AnalogOutputHeader *s_Header:Anlog Output Header |
-| Pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-
-int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_AnalogOutputHeader *s_Header)
-{
- unsigned short w_Temp;
- /* No of channels for 1st hard component */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + 10);
- s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
- /* Resolution for 1st hard component */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + 16);
- s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF;
- return 0;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name : int i_EepromReadAnlogInputHeader(unsigned short |
-| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
-| unsigned short w_Address,struct str_AnalogInputHeader *s_Header) |
-+----------------------------------------------------------------------------+
-| Task : Read Nalog Output Header |
-+----------------------------------------------------------------------------+
-| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address |
-| |
-| char *pc_PCIChipInformation : PCI Chip Type. |
-| |
-| struct str_AnalogInputHeader *s_Header:Anlog Input Header |
-| Pointer |
-+----------------------------------------------------------------------------+
-| Output Parameters : - |
-+----------------------------------------------------------------------------+
-| Return Value : 0 |
-+----------------------------------------------------------------------------+
-*/
-
-/* Reads only for ONE hardware component */
-int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
- char *pc_PCIChipInformation, unsigned short w_Address,
- struct str_AnalogInputHeader *s_Header)
-{
- unsigned short w_Temp, w_Offset;
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + 10);
- s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
- s_Header->w_MinConvertTiming =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 16);
- s_Header->w_MinDelayTiming =
- w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
- 0x100 + w_Address + 30);
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + 20);
- s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */
-
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); /* reading Y */
- w_Temp = w_Temp & 0x00FF;
- if (w_Temp) /* Y>0 */
- {
- w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); /* offset of first analog input single header */
- w_Offset = w_Offset + 2; /* resolution */
- } else /* Y=0 */
- {
- w_Offset = 74;
- w_Offset = w_Offset + 2; /* resolution */
- }
-
-/* read Resolution */
- w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
- pc_PCIChipInformation, 0x100 + w_Address + w_Offset);
- s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */
-
- return 0;
}