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