root/drivers/misc/eeprom/eeprom_93cx6.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. eeprom_93cx6_pulse_high
  2. eeprom_93cx6_pulse_low
  3. eeprom_93cx6_startup
  4. eeprom_93cx6_cleanup
  5. eeprom_93cx6_write_bits
  6. eeprom_93cx6_read_bits
  7. eeprom_93cx6_read
  8. eeprom_93cx6_multiread
  9. eeprom_93cx6_readb
  10. eeprom_93cx6_multireadb
  11. eeprom_93cx6_wren
  12. eeprom_93cx6_write

   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 
  16 MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
  17 MODULE_VERSION("1.0");
  18 MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
  19 MODULE_LICENSE("GPL");
  20 
  21 static 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 
  34 static 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 
  47 static 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 
  67 static 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 
  84 static 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 
 123 static 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  */
 172 void 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 }
 199 EXPORT_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  */
 214 void 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 }
 226 EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
 227 
 228 /**
 229  * eeprom_93cx6_readb - Read a byte from eeprom
 230  * @eeprom: Pointer to eeprom structure
 231  * @word: 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  */
 237 void 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 }
 266 EXPORT_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  * @words: 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  */
 278 void 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 }
 286 EXPORT_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  */
 296 void 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 }
 313 EXPORT_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  */
 328 void 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 }
 372 EXPORT_SYMBOL_GPL(eeprom_93cx6_write);

/* [<][>][^][v][top][bottom][index][help] */