//---------------------------------------------------------------------------------------- // Procedure: e100_eeprom_size // // Description: This routine determines the size of the EEPROM. This value should be // checked for validity - ie. is it too big or too small. The size returned // is then passed to the read/write functions. // // Returns: // Size of the eeprom, or zero if an error occured //---------------------------------------------------------------------------------------- u16 e100_eeprom_size(struct e100_private *adapter) { u16 x, size = 1; // must be one to accumulate a product // if we've already stored this data, read from memory if (adapter->eeprom_size) { return adapter->eeprom_size; } // otherwise, read from the eeprom // Set EEPROM semaphore. if (adapter->rev_id >= D102_REV_ID) { if (!eeprom_set_semaphore(adapter)) return 0; } // enable the eeprom by setting EECS. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter)); x &= ~(EEDI | EEDO | EESK); x |= EECS; writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter)); // write the read opcode shift_out_bits(adapter, EEPROM_READ_OPCODE, 3); // experiment to discover the size of the eeprom. request register zero // and wait for the eeprom to tell us it has accepted the entire address. x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter)); do { size *= 2; // each bit of address doubles eeprom size x |= EEDO; // set bit to detect "dummy zero" x &= ~EEDI; // address consists of all zeros writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter)); udelay(EEPROM_STALL_TIME); raise_clock(adapter, &x); lower_clock(adapter, &x); // check for "dummy zero" x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter)); if (size > EEPROM_MAX_WORD_SIZE) { size = 0; break; } } while (x & EEDO); // read in the value requested (void) shift_in_bits(adapter); e100_eeprom_cleanup(adapter); // Clear EEPROM Semaphore. if (adapter->rev_id >= D102_REV_ID) { eeprom_reset_semaphore(adapter); } return size; }
u16 e100_eeprom_read(struct e100_private *adapter, u16 reg) { u16 x, data, bits; // Set EEPROM semaphore. if (adapter->rev_id >= D102_REV_ID) { if (!eeprom_set_semaphore(adapter)) return 0; } // eeprom size is initialized to zero if (!adapter->eeprom_size) adapter->eeprom_size = e100_eeprom_size(adapter); bits = eeprom_address_size(adapter->eeprom_size); // select EEPROM, reset bits, set EECS x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter)); x &= ~(EEDI | EEDO | EESK); x |= EECS; writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter)); // write the read opcode and register number in that order // The opcode is 3bits in length, reg is 'bits' bits long shift_out_bits(adapter, EEPROM_READ_OPCODE, 3); shift_out_bits(adapter, reg, bits); // Now read the data (16 bits) in from the selected EEPROM word data = shift_in_bits(adapter); e100_eeprom_cleanup(adapter); // Clear EEPROM Semaphore. if (adapter->rev_id >= D102_REV_ID) { eeprom_reset_semaphore(adapter); } return data; }
u16 r8712_eeprom_read16(struct _adapter *padapter, u16 reg) /*ReadEEprom*/ { u16 x; u16 data = 0; u8 tmp8_ori, tmp8_new, tmp8_clk_ori, tmp8_clk_new; tmp8_ori = r8712_read8(padapter, 0x102502f1); tmp8_new = tmp8_ori & 0xf7; if (tmp8_ori != tmp8_new) r8712_write8(padapter, 0x102502f1, tmp8_new); tmp8_clk_ori = r8712_read8(padapter, 0x10250003); tmp8_clk_new = tmp8_clk_ori | 0x20; if (tmp8_clk_new != tmp8_clk_ori) r8712_write8(padapter, 0x10250003, tmp8_clk_new); if (padapter->bSurpriseRemoved == true) goto out; /* select EEPROM, reset bits, set _EECS */ x = r8712_read8(padapter, EE_9346CR); if (padapter->bSurpriseRemoved == true) goto out; x &= ~(_EEDI | _EEDO | _EESK | _EEM0); x |= _EEM1 | _EECS; r8712_write8(padapter, EE_9346CR, (unsigned char)x); /* write the read opcode and register number in that order * The opcode is 3bits in length, reg is 6 bits long */ shift_out_bits(padapter, EEPROM_READ_OPCODE, 3); shift_out_bits(padapter, reg, padapter->EepromAddressSize); /* Now read the data (16 bits) in from the selected EEPROM word */ data = shift_in_bits(padapter); eeprom_clean(padapter); out: if (tmp8_clk_new != tmp8_clk_ori) r8712_write8(padapter, 0x10250003, tmp8_clk_ori); if (tmp8_new != tmp8_ori) r8712_write8(padapter, 0x102502f1, tmp8_ori); return data; }