aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorBen Dooks <ben@simtec.co.uk>2011-11-21 03:57:57 -0500
committerDavid S. Miller <davem@davemloft.net>2011-11-26 14:59:39 -0500
commit072bc80156729f853e8bcafe1b17c48c74462887 (patch)
treefd48bf8aa8e730a75ea40375275e75afa0d2994e /drivers/misc
parentb30f8bdcfa7dd05f4268348f3388ff903132f28e (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')
-rw-r--r--drivers/misc/eeprom/eeprom_93cx6.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/misc/eeprom/eeprom_93cx6.c b/drivers/misc/eeprom/eeprom_93cx6.c
index a6037af6f07..0ff4b02177b 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,
234} 234}
235EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread); 235EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
236 236
237/**
238 * eeprom_93cx6_wren - set the write enable state
239 * @eeprom: Pointer to eeprom structure
240 * @enable: true to enable writes, otherwise disable writes
241 *
242 * Set the EEPROM write enable state to either allow or deny
243 * writes depending on the @enable value.
244 */
245void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable)
246{
247 u16 command;
248
249 /* start the command */
250 eeprom_93cx6_startup(eeprom);
251
252 /* create command to enable/disable */
253
254 command = enable ? PCI_EEPROM_EWEN_OPCODE : PCI_EEPROM_EWDS_OPCODE;
255 command <<= (eeprom->width - 2);
256
257 eeprom_93cx6_write_bits(eeprom, command,
258 PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
259
260 eeprom_93cx6_cleanup(eeprom);
261}
262EXPORT_SYMBOL_GPL(eeprom_93cx6_wren);
263
264/**
265 * eeprom_93cx6_write - write data to the EEPROM
266 * @eeprom: Pointer to eeprom structure
267 * @addr: Address to write data to.
268 * @data: The data to write to address @addr.
269 *
270 * Write the @data to the specified @addr in the EEPROM and
271 * waiting for the device to finish writing.
272 *
273 * Note, since we do not expect large number of write operations
274 * we delay in between parts of the operation to avoid using excessive
275 * amounts of CPU time busy waiting.
276 */
277void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, u8 addr, u16 data)
278{
279 int timeout = 100;
280 u16 command;
281
282 /* start the command */
283 eeprom_93cx6_startup(eeprom);
284
285 command = PCI_EEPROM_WRITE_OPCODE << eeprom->width;
286 command |= addr;
287
288 /* send write command */
289 eeprom_93cx6_write_bits(eeprom, command,
290 PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
291
292 /* send data */
293 eeprom_93cx6_write_bits(eeprom, data, 16);
294
295 /* get ready to check for busy */
296 eeprom->drive_data = 0;
297 eeprom->reg_chip_select = 1;
298 eeprom->register_write(eeprom);
299
300 /* wait at-least 250ns to get DO to be the busy signal */
301 usleep_range(1000, 2000);
302
303 /* wait for DO to go high to signify finish */
304
305 while (true) {
306 eeprom->register_read(eeprom);
307
308 if (eeprom->reg_data_out)
309 break;
310
311 usleep_range(1000, 2000);
312
313 if (--timeout <= 0) {
314 printk(KERN_ERR "%s: timeout\n", __func__);
315 break;
316 }
317 }
318
319 eeprom_93cx6_cleanup(eeprom);
320}
321EXPORT_SYMBOL_GPL(eeprom_93cx6_write);