Commit 072bc80156729f853e8bcafe1b17c48c74462887
Committed by
David S. Miller
1 parent
b30f8bdcfa
Exists in
master
and in
20 other branches
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>
Showing 2 changed files with 91 additions and 0 deletions Side-by-side Diff
drivers/misc/eeprom/eeprom_93cx6.c
... | ... | @@ -233,4 +233,90 @@ |
233 | 233 | } |
234 | 234 | } |
235 | 235 | EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread); |
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 | + */ | |
245 | +void 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 | +} | |
262 | +EXPORT_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 | + */ | |
277 | +void 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 | +} | |
321 | +EXPORT_SYMBOL_GPL(eeprom_93cx6_write); |
include/linux/eeprom_93cx6.h
... | ... | @@ -33,6 +33,7 @@ |
33 | 33 | #define PCI_EEPROM_WIDTH_93C86 8 |
34 | 34 | #define PCI_EEPROM_WIDTH_OPCODE 3 |
35 | 35 | #define PCI_EEPROM_WRITE_OPCODE 0x05 |
36 | +#define PCI_EEPROM_ERASE_OPCODE 0x07 | |
36 | 37 | #define PCI_EEPROM_READ_OPCODE 0x06 |
37 | 38 | #define PCI_EEPROM_EWDS_OPCODE 0x10 |
38 | 39 | #define PCI_EEPROM_EWEN_OPCODE 0x13 |
... | ... | @@ -74,4 +75,9 @@ |
74 | 75 | const u8 word, u16 *data); |
75 | 76 | extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, |
76 | 77 | const u8 word, __le16 *data, const u16 words); |
78 | + | |
79 | +extern void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable); | |
80 | + | |
81 | +extern void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, | |
82 | + u8 addr, u16 data); |