diff options
| author | Ben Dooks <ben@simtec.co.uk> | 2011-11-21 08:57:57 +0000 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-11-26 14:59:39 -0500 | 
| commit | 072bc80156729f853e8bcafe1b17c48c74462887 (patch) | |
| tree | fd48bf8aa8e730a75ea40375275e75afa0d2994e /drivers/misc/eeprom | |
| parent | b30f8bdcfa7dd05f4268348f3388ff903132f28e (diff) | |
eeprom_93cx6: Add write support
Add support for writing data to EEPROM.
Signed-off-by: Ben Dooks <ben@simtec.co.uk>
Cc: Wolfram Sang <w.sang@pengutronix.de>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Linux Kernel <linux-kernel@vger.kernel.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/misc/eeprom')
| -rw-r--r-- | drivers/misc/eeprom/eeprom_93cx6.c | 85 | 
1 files changed, 85 insertions, 0 deletions
| diff --git a/drivers/misc/eeprom/eeprom_93cx6.c b/drivers/misc/eeprom/eeprom_93cx6.c index a6037af6f076..0ff4b02177be 100644 --- a/drivers/misc/eeprom/eeprom_93cx6.c +++ b/drivers/misc/eeprom/eeprom_93cx6.c @@ -234,3 +234,88 @@ void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,  }  EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread); +/** + * eeprom_93cx6_wren - set the write enable state + * @eeprom: Pointer to eeprom structure + * @enable: true to enable writes, otherwise disable writes + * + * Set the EEPROM write enable state to either allow or deny + * writes depending on the @enable value. + */ +void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable) +{ +	u16 command; + +	/* start the command */ +	eeprom_93cx6_startup(eeprom); + +	/* create command to enable/disable */ + +	command = enable ? PCI_EEPROM_EWEN_OPCODE : PCI_EEPROM_EWDS_OPCODE; +	command <<= (eeprom->width - 2); + +	eeprom_93cx6_write_bits(eeprom, command, +				PCI_EEPROM_WIDTH_OPCODE + eeprom->width); + +	eeprom_93cx6_cleanup(eeprom); +} +EXPORT_SYMBOL_GPL(eeprom_93cx6_wren); + +/** + * eeprom_93cx6_write - write data to the EEPROM + * @eeprom: Pointer to eeprom structure + * @addr: Address to write data to. + * @data: The data to write to address @addr. + * + * Write the @data to the specified @addr in the EEPROM and + * waiting for the device to finish writing. + * + * Note, since we do not expect large number of write operations + * we delay in between parts of the operation to avoid using excessive + * amounts of CPU time busy waiting. + */ +void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, u8 addr, u16 data) +{ +	int timeout = 100; +	u16 command; + +	/* start the command */ +	eeprom_93cx6_startup(eeprom); + +	command = PCI_EEPROM_WRITE_OPCODE << eeprom->width; +	command |= addr; + +	/* send write command */ +	eeprom_93cx6_write_bits(eeprom, command, +				PCI_EEPROM_WIDTH_OPCODE + eeprom->width); + +	/* send data */ +	eeprom_93cx6_write_bits(eeprom, data, 16); + +	/* get ready to check for busy */ +	eeprom->drive_data = 0; +	eeprom->reg_chip_select = 1; +	eeprom->register_write(eeprom); + +	/* wait at-least 250ns to get DO to be the busy signal */ +	usleep_range(1000, 2000); + +	/* wait for DO to go high to signify finish */ + +	while (true) { +		eeprom->register_read(eeprom); + +		if (eeprom->reg_data_out) +			break; + +		usleep_range(1000, 2000); + +		if (--timeout <= 0) { +			printk(KERN_ERR "%s: timeout\n", __func__); +			break; +		} +	} + +	eeprom_93cx6_cleanup(eeprom); +} +EXPORT_SYMBOL_GPL(eeprom_93cx6_write); | 
