Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/drivers/eeprom/93cx6.c need to be fixed.

0001 /*                    The Quest Operating System
0002  *  Copyright (C) 2005-2010  Richard West, Boston University
0003  *
0004  *  This program is free software: you can redistribute it and/or modify
0005  *  it under the terms of the GNU General Public License as published by
0006  *  the Free Software Foundation, either version 3 of the License, or
0007  *  (at your option) any later version.
0008  *
0009  *  This program is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 
0018 /* Based on the Linux driver:
0019  *     Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
0020  *       <http://rt2x00.serialmonkey.com>
0021  *
0022  *       This program is free software; you can redistribute it and/or modify
0023  *       it under the terms of the GNU General Public License as published by
0024  *       the Free Software Foundation; either version 2 of the License, or
0025  *       (at your option) any later version.
0026  *
0027  */
0028 
0029 /* Abstract: EEPROM reader routines for 93cx6 chipsets. */
0030 
0031 #include <kernel.h>
0032 #include <drivers/eeprom/93cx6.h>
0033 
0034 #define udelay(x) tsc_delay_usec (x)
0035 
0036 static inline void
0037 eeprom_93cx6_pulse_high (struct eeprom_93cx6 *eeprom)
0038 {
0039   eeprom->reg_data_clock = 1;
0040   eeprom->register_write (eeprom);
0041 
0042   /*
0043    * Add a short delay for the pulse to work.
0044    * According to the specifications the "maximum minimum"
0045    * time should be 450ns.
0046    */
0047   //ndelay(450);
0048   udelay (1);
0049 }
0050 
0051 static inline void
0052 eeprom_93cx6_pulse_low (struct eeprom_93cx6 *eeprom)
0053 {
0054   eeprom->reg_data_clock = 0;
0055   eeprom->register_write (eeprom);
0056 
0057   /*
0058    * Add a short delay for the pulse to work.
0059    * According to the specifications the "maximum minimum"
0060    * time should be 450ns.
0061    */
0062   //ndelay(450);
0063   udelay (1);
0064 }
0065 
0066 static void
0067 eeprom_93cx6_startup (struct eeprom_93cx6 *eeprom)
0068 {
0069   /*
0070    * Clear all flags, and enable chip select.
0071    */
0072   eeprom->register_read (eeprom);
0073   eeprom->reg_data_in = 0;
0074   eeprom->reg_data_out = 0;
0075   eeprom->reg_data_clock = 0;
0076   eeprom->reg_chip_select = 1;
0077   eeprom->register_write (eeprom);
0078 
0079   /*
0080    * kick a pulse.
0081    */
0082   eeprom_93cx6_pulse_high (eeprom);
0083   eeprom_93cx6_pulse_low (eeprom);
0084 }
0085 
0086 static void
0087 eeprom_93cx6_cleanup (struct eeprom_93cx6 *eeprom)
0088 {
0089   /*
0090    * Clear chip_select and data_in flags.
0091    */
0092   eeprom->register_read (eeprom);
0093   eeprom->reg_data_in = 0;
0094   eeprom->reg_chip_select = 0;
0095   eeprom->register_write (eeprom);
0096 
0097   /*
0098    * kick a pulse.
0099    */
0100   eeprom_93cx6_pulse_high (eeprom);
0101   eeprom_93cx6_pulse_low (eeprom);
0102 }
0103 
0104 static void
0105 eeprom_93cx6_write_bits (struct eeprom_93cx6 *eeprom,
0106                          const uint16 data, const uint16 count)
0107 {
0108   unsigned int i;
0109 
0110   eeprom->register_read (eeprom);
0111 
0112   /*
0113    * Clear data flags.
0114    */
0115   eeprom->reg_data_in = 0;
0116   eeprom->reg_data_out = 0;
0117 
0118   /*
0119    * Start writing all bits.
0120    */
0121   for (i = count; i > 0; i--) {
0122     /*
0123      * Check if this bit needs to be set.
0124      */
0125     eeprom->reg_data_in = ! !(data & (1 << (i - 1)));
0126 
0127     /*
0128      * Write the bit to the eeprom register.
0129      */
0130     eeprom->register_write (eeprom);
0131 
0132     /*
0133      * Kick a pulse.
0134      */
0135     eeprom_93cx6_pulse_high (eeprom);
0136     eeprom_93cx6_pulse_low (eeprom);
0137   }
0138 
0139   eeprom->reg_data_in = 0;
0140   eeprom->register_write (eeprom);
0141 }
0142 
0143 static void
0144 eeprom_93cx6_read_bits (struct eeprom_93cx6 *eeprom,
0145                         uint16 * data, const uint16 count)
0146 {
0147   unsigned int i;
0148   uint16 buf = 0;
0149 
0150   eeprom->register_read (eeprom);
0151 
0152   /*
0153    * Clear data flags.
0154    */
0155   eeprom->reg_data_in = 0;
0156   eeprom->reg_data_out = 0;
0157 
0158   /*
0159    * Start reading all bits.
0160    */
0161   for (i = count; i > 0; i--) {
0162     eeprom_93cx6_pulse_high (eeprom);
0163 
0164     eeprom->register_read (eeprom);
0165 
0166     /*
0167      * Clear data_in flag.
0168      */
0169     eeprom->reg_data_in = 0;
0170 
0171     /*
0172      * Read if the bit has been set.
0173      */
0174     if (eeprom->reg_data_out)
0175       buf |= (1 << (i - 1));
0176 
0177     eeprom_93cx6_pulse_low (eeprom);
0178   }
0179 
0180   *data = buf;
0181 }
0182 
0183 /**
0184  * eeprom_93cx6_read - Read multiple words from eeprom
0185  * @eeprom: Pointer to eeprom structure
0186  * @word: Word index from where we should start reading
0187  * @data: target pointer where the information will have to be stored
0188  *
0189  * This function will read the eeprom data as host-endian word
0190  * into the given data pointer.
0191  */
0192 void
0193 eeprom_93cx6_read (struct eeprom_93cx6 *eeprom, const uint8 word,
0194                    uint16 * data)
0195 {
0196   uint16 command;
0197 
0198   /*
0199    * Initialize the eeprom register
0200    */
0201   eeprom_93cx6_startup (eeprom);
0202 
0203   /*
0204    * Select the read opcode and the word to be read.
0205    */
0206   command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
0207   eeprom_93cx6_write_bits (eeprom, command,
0208                            PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
0209 
0210   /*
0211    * Read the requested 16 bits.
0212    */
0213   eeprom_93cx6_read_bits (eeprom, data, 16);
0214 
0215   /*
0216    * Cleanup eeprom register.
0217    */
0218   eeprom_93cx6_cleanup (eeprom);
0219 }
0220 
0221 /**
0222  * eeprom_93cx6_multiread - Read multiple words from eeprom
0223  * @eeprom: Pointer to eeprom structure
0224  * @word: Word index from where we should start reading
0225  * @data: target pointer where the information will have to be stored
0226  * @words: Number of words that should be read.
0227  *
0228  * This function will read all requested words from the eeprom,
0229  * this is done by calling eeprom_93cx6_read() multiple times.
0230  * But with the additional change that while the eeprom_93cx6_read
0231  * will return host ordered bytes, this method will return little
0232  * endian words.
0233  */
0234 void
0235 eeprom_93cx6_multiread (struct eeprom_93cx6 *eeprom, const uint8 word,
0236                         uint16 * data, const uint16 words)
0237 {
0238   unsigned int i;
0239   uint16 tmp;
0240 
0241   for (i = 0; i < words; i++) {
0242     tmp = 0;
0243     eeprom_93cx6_read (eeprom, word + i, &tmp);
0244     data[i] = tmp;
0245   }
0246 }
0247 
0248 
0249 /*
0250  * Local Variables:
0251  * indent-tabs-mode: nil
0252  * mode: C
0253  * c-file-style: "gnu"
0254  * c-basic-offset: 2
0255  * End:
0256  */
0257 
0258 /* vi: set et sw=2 sts=2: */