eeprom_93cx6.c (8634B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2004 - 2006 rt2x00 SourceForge Project 4 * <http://rt2x00.serialmonkey.com> 5 * 6 * Module: eeprom_93cx6 7 * Abstract: EEPROM reader routines for 93cx6 chipsets. 8 * Supported chipsets: 93c46 & 93c66. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/module.h> 13#include <linux/delay.h> 14#include <linux/eeprom_93cx6.h> 15 16MODULE_AUTHOR("http://rt2x00.serialmonkey.com"); 17MODULE_VERSION("1.0"); 18MODULE_DESCRIPTION("EEPROM 93cx6 chip driver"); 19MODULE_LICENSE("GPL"); 20 21static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom) 22{ 23 eeprom->reg_data_clock = 1; 24 eeprom->register_write(eeprom); 25 26 /* 27 * Add a short delay for the pulse to work. 28 * According to the specifications the "maximum minimum" 29 * time should be 450ns. 30 */ 31 ndelay(450); 32} 33 34static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom) 35{ 36 eeprom->reg_data_clock = 0; 37 eeprom->register_write(eeprom); 38 39 /* 40 * Add a short delay for the pulse to work. 41 * According to the specifications the "maximum minimum" 42 * time should be 450ns. 43 */ 44 ndelay(450); 45} 46 47static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom) 48{ 49 /* 50 * Clear all flags, and enable chip select. 51 */ 52 eeprom->register_read(eeprom); 53 eeprom->reg_data_in = 0; 54 eeprom->reg_data_out = 0; 55 eeprom->reg_data_clock = 0; 56 eeprom->reg_chip_select = 1; 57 eeprom->drive_data = 1; 58 eeprom->register_write(eeprom); 59 60 /* 61 * kick a pulse. 62 */ 63 eeprom_93cx6_pulse_high(eeprom); 64 eeprom_93cx6_pulse_low(eeprom); 65} 66 67static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom) 68{ 69 /* 70 * Clear chip_select and data_in flags. 71 */ 72 eeprom->register_read(eeprom); 73 eeprom->reg_data_in = 0; 74 eeprom->reg_chip_select = 0; 75 eeprom->register_write(eeprom); 76 77 /* 78 * kick a pulse. 79 */ 80 eeprom_93cx6_pulse_high(eeprom); 81 eeprom_93cx6_pulse_low(eeprom); 82} 83 84static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom, 85 const u16 data, const u16 count) 86{ 87 unsigned int i; 88 89 eeprom->register_read(eeprom); 90 91 /* 92 * Clear data flags. 93 */ 94 eeprom->reg_data_in = 0; 95 eeprom->reg_data_out = 0; 96 eeprom->drive_data = 1; 97 98 /* 99 * Start writing all bits. 100 */ 101 for (i = count; i > 0; i--) { 102 /* 103 * Check if this bit needs to be set. 104 */ 105 eeprom->reg_data_in = !!(data & (1 << (i - 1))); 106 107 /* 108 * Write the bit to the eeprom register. 109 */ 110 eeprom->register_write(eeprom); 111 112 /* 113 * Kick a pulse. 114 */ 115 eeprom_93cx6_pulse_high(eeprom); 116 eeprom_93cx6_pulse_low(eeprom); 117 } 118 119 eeprom->reg_data_in = 0; 120 eeprom->register_write(eeprom); 121} 122 123static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom, 124 u16 *data, const u16 count) 125{ 126 unsigned int i; 127 u16 buf = 0; 128 129 eeprom->register_read(eeprom); 130 131 /* 132 * Clear data flags. 133 */ 134 eeprom->reg_data_in = 0; 135 eeprom->reg_data_out = 0; 136 eeprom->drive_data = 0; 137 138 /* 139 * Start reading all bits. 140 */ 141 for (i = count; i > 0; i--) { 142 eeprom_93cx6_pulse_high(eeprom); 143 144 eeprom->register_read(eeprom); 145 146 /* 147 * Clear data_in flag. 148 */ 149 eeprom->reg_data_in = 0; 150 151 /* 152 * Read if the bit has been set. 153 */ 154 if (eeprom->reg_data_out) 155 buf |= (1 << (i - 1)); 156 157 eeprom_93cx6_pulse_low(eeprom); 158 } 159 160 *data = buf; 161} 162 163/** 164 * eeprom_93cx6_read - Read a word from eeprom 165 * @eeprom: Pointer to eeprom structure 166 * @word: Word index from where we should start reading 167 * @data: target pointer where the information will have to be stored 168 * 169 * This function will read the eeprom data as host-endian word 170 * into the given data pointer. 171 */ 172void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word, 173 u16 *data) 174{ 175 u16 command; 176 177 /* 178 * Initialize the eeprom register 179 */ 180 eeprom_93cx6_startup(eeprom); 181 182 /* 183 * Select the read opcode and the word to be read. 184 */ 185 command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word; 186 eeprom_93cx6_write_bits(eeprom, command, 187 PCI_EEPROM_WIDTH_OPCODE + eeprom->width); 188 189 /* 190 * Read the requested 16 bits. 191 */ 192 eeprom_93cx6_read_bits(eeprom, data, 16); 193 194 /* 195 * Cleanup eeprom register. 196 */ 197 eeprom_93cx6_cleanup(eeprom); 198} 199EXPORT_SYMBOL_GPL(eeprom_93cx6_read); 200 201/** 202 * eeprom_93cx6_multiread - Read multiple words from eeprom 203 * @eeprom: Pointer to eeprom structure 204 * @word: Word index from where we should start reading 205 * @data: target pointer where the information will have to be stored 206 * @words: Number of words that should be read. 207 * 208 * This function will read all requested words from the eeprom, 209 * this is done by calling eeprom_93cx6_read() multiple times. 210 * But with the additional change that while the eeprom_93cx6_read 211 * will return host ordered bytes, this method will return little 212 * endian words. 213 */ 214void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word, 215 __le16 *data, const u16 words) 216{ 217 unsigned int i; 218 u16 tmp; 219 220 for (i = 0; i < words; i++) { 221 tmp = 0; 222 eeprom_93cx6_read(eeprom, word + i, &tmp); 223 data[i] = cpu_to_le16(tmp); 224 } 225} 226EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread); 227 228/** 229 * eeprom_93cx6_readb - Read a byte from eeprom 230 * @eeprom: Pointer to eeprom structure 231 * @byte: Byte index from where we should start reading 232 * @data: target pointer where the information will have to be stored 233 * 234 * This function will read a byte of the eeprom data 235 * into the given data pointer. 236 */ 237void eeprom_93cx6_readb(struct eeprom_93cx6 *eeprom, const u8 byte, 238 u8 *data) 239{ 240 u16 command; 241 u16 tmp; 242 243 /* 244 * Initialize the eeprom register 245 */ 246 eeprom_93cx6_startup(eeprom); 247 248 /* 249 * Select the read opcode and the byte to be read. 250 */ 251 command = (PCI_EEPROM_READ_OPCODE << (eeprom->width + 1)) | byte; 252 eeprom_93cx6_write_bits(eeprom, command, 253 PCI_EEPROM_WIDTH_OPCODE + eeprom->width + 1); 254 255 /* 256 * Read the requested 8 bits. 257 */ 258 eeprom_93cx6_read_bits(eeprom, &tmp, 8); 259 *data = tmp & 0xff; 260 261 /* 262 * Cleanup eeprom register. 263 */ 264 eeprom_93cx6_cleanup(eeprom); 265} 266EXPORT_SYMBOL_GPL(eeprom_93cx6_readb); 267 268/** 269 * eeprom_93cx6_multireadb - Read multiple bytes from eeprom 270 * @eeprom: Pointer to eeprom structure 271 * @byte: Index from where we should start reading 272 * @data: target pointer where the information will have to be stored 273 * @bytes: Number of bytes that should be read. 274 * 275 * This function will read all requested bytes from the eeprom, 276 * this is done by calling eeprom_93cx6_readb() multiple times. 277 */ 278void eeprom_93cx6_multireadb(struct eeprom_93cx6 *eeprom, const u8 byte, 279 u8 *data, const u16 bytes) 280{ 281 unsigned int i; 282 283 for (i = 0; i < bytes; i++) 284 eeprom_93cx6_readb(eeprom, byte + i, &data[i]); 285} 286EXPORT_SYMBOL_GPL(eeprom_93cx6_multireadb); 287 288/** 289 * eeprom_93cx6_wren - set the write enable state 290 * @eeprom: Pointer to eeprom structure 291 * @enable: true to enable writes, otherwise disable writes 292 * 293 * Set the EEPROM write enable state to either allow or deny 294 * writes depending on the @enable value. 295 */ 296void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable) 297{ 298 u16 command; 299 300 /* start the command */ 301 eeprom_93cx6_startup(eeprom); 302 303 /* create command to enable/disable */ 304 305 command = enable ? PCI_EEPROM_EWEN_OPCODE : PCI_EEPROM_EWDS_OPCODE; 306 command <<= (eeprom->width - 2); 307 308 eeprom_93cx6_write_bits(eeprom, command, 309 PCI_EEPROM_WIDTH_OPCODE + eeprom->width); 310 311 eeprom_93cx6_cleanup(eeprom); 312} 313EXPORT_SYMBOL_GPL(eeprom_93cx6_wren); 314 315/** 316 * eeprom_93cx6_write - write data to the EEPROM 317 * @eeprom: Pointer to eeprom structure 318 * @addr: Address to write data to. 319 * @data: The data to write to address @addr. 320 * 321 * Write the @data to the specified @addr in the EEPROM and 322 * waiting for the device to finish writing. 323 * 324 * Note, since we do not expect large number of write operations 325 * we delay in between parts of the operation to avoid using excessive 326 * amounts of CPU time busy waiting. 327 */ 328void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, u8 addr, u16 data) 329{ 330 int timeout = 100; 331 u16 command; 332 333 /* start the command */ 334 eeprom_93cx6_startup(eeprom); 335 336 command = PCI_EEPROM_WRITE_OPCODE << eeprom->width; 337 command |= addr; 338 339 /* send write command */ 340 eeprom_93cx6_write_bits(eeprom, command, 341 PCI_EEPROM_WIDTH_OPCODE + eeprom->width); 342 343 /* send data */ 344 eeprom_93cx6_write_bits(eeprom, data, 16); 345 346 /* get ready to check for busy */ 347 eeprom->drive_data = 0; 348 eeprom->reg_chip_select = 1; 349 eeprom->register_write(eeprom); 350 351 /* wait at-least 250ns to get DO to be the busy signal */ 352 usleep_range(1000, 2000); 353 354 /* wait for DO to go high to signify finish */ 355 356 while (true) { 357 eeprom->register_read(eeprom); 358 359 if (eeprom->reg_data_out) 360 break; 361 362 usleep_range(1000, 2000); 363 364 if (--timeout <= 0) { 365 printk(KERN_ERR "%s: timeout\n", __func__); 366 break; 367 } 368 } 369 370 eeprom_93cx6_cleanup(eeprom); 371} 372EXPORT_SYMBOL_GPL(eeprom_93cx6_write);