Exemplo n.º 1
0
//----------------------------------------------------------------------------------------
// 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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
void r8712_eeprom_write16(struct _adapter *padapter, u16 reg, u16 data)
{
	u8 x;
	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);
	x = r8712_read8(padapter, EE_9346CR);
	x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
	x |= _EEM1 | _EECS;
	r8712_write8(padapter, EE_9346CR, x);
	shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5);
	if (padapter->EepromAddressSize == 8)	/*CF+ and SDIO*/
		shift_out_bits(padapter, 0, 6);
	else	/* USB */
		shift_out_bits(padapter, 0, 4);
	standby(padapter);
	/* Erase this particular word.  Write the erase opcode and register
	 * number in that order. The opcode is 3bits in length; reg is 6
	 * bits long.
	 */
	standby(padapter);
	/* write the new word to the EEPROM
	 * send the write opcode the EEPORM
	 */
	shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3);
	/* select which word in the EEPROM that we are writing to. */
	shift_out_bits(padapter, reg, padapter->EepromAddressSize);
	/* write the data to the selected EEPROM word. */
	shift_out_bits(padapter, data, 16);
	if (wait_eeprom_cmd_done(padapter)) {
		standby(padapter);
		shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5);
		shift_out_bits(padapter, reg, 4);
		eeprom_clean(padapter);
	}
	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);
}
Exemplo n.º 5
0
//----------------------------------------------------------------------------------------
// Procedure:   e100_eeprom_write_word
//
// Description: This routine writes a word to a specific EEPROM location without.
//              taking EEPROM semaphore and updating checksum. 
//              Use e100_eeprom_write_block for the EEPROM update
// Arguments: reg - The EEPROM word that we are going to write to.
//            data - The data (word) that we are going to write to the EEPROM.
//----------------------------------------------------------------------------------------
static void
e100_eeprom_write_word(struct e100_private *adapter, u16 reg, u16 data)
{
	u16 x;
	u16 bits;

	bits = eeprom_address_size(adapter->eeprom_size);

	/* select EEPROM, mask off ASIC and reset bits, set EECS */
	x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
	x &= ~(EEDI | EEDO | EESK);
	writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
	readw(&(adapter->scb->scb_status)); /* flush command to card */
	udelay(EEPROM_STALL_TIME);
	x |= EECS;
	writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));

	shift_out_bits(adapter, EEPROM_EWEN_OPCODE, 5);
	shift_out_bits(adapter, reg, (u16) (bits - 2));
	if (!eeprom_wait_cmd_done(adapter))
		return;

	/* write the new word to the EEPROM & send the write opcode the EEPORM */
	shift_out_bits(adapter, EEPROM_WRITE_OPCODE, 3);

	/* select which word in the EEPROM that we are writing to */
	shift_out_bits(adapter, reg, bits);

	/* write the data to the selected EEPROM word */
	shift_out_bits(adapter, data, 16);
	if (!eeprom_wait_cmd_done(adapter))
		return;

	shift_out_bits(adapter, EEPROM_EWDS_OPCODE, 5);
	shift_out_bits(adapter, reg, (u16) (bits - 2));
	if (!eeprom_wait_cmd_done(adapter))
		return;

	e100_eeprom_cleanup(adapter);
}