Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.23-rc3 241 lines 5.5 kB view raw
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 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the 17 Free Software Foundation, Inc., 18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 */ 20 21/* 22 Module: eeprom_93cx6 23 Abstract: EEPROM reader routines for 93cx6 chipsets. 24 Supported chipsets: 93c46 & 93c66. 25 */ 26 27#include <linux/kernel.h> 28#include <linux/module.h> 29#include <linux/version.h> 30#include <linux/delay.h> 31#include <linux/eeprom_93cx6.h> 32 33MODULE_AUTHOR("http://rt2x00.serialmonkey.com"); 34MODULE_VERSION("1.0"); 35MODULE_DESCRIPTION("EEPROM 93cx6 chip driver"); 36MODULE_LICENSE("GPL"); 37 38static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom) 39{ 40 eeprom->reg_data_clock = 1; 41 eeprom->register_write(eeprom); 42 43 /* 44 * Add a short delay for the pulse to work. 45 * According to the specifications the "maximum minimum" 46 * time should be 450ns. 47 */ 48 ndelay(450); 49} 50 51static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom) 52{ 53 eeprom->reg_data_clock = 0; 54 eeprom->register_write(eeprom); 55 56 /* 57 * Add a short delay for the pulse to work. 58 * According to the specifications the "maximum minimum" 59 * time should be 450ns. 60 */ 61 ndelay(450); 62} 63 64static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom) 65{ 66 /* 67 * Clear all flags, and enable chip select. 68 */ 69 eeprom->register_read(eeprom); 70 eeprom->reg_data_in = 0; 71 eeprom->reg_data_out = 0; 72 eeprom->reg_data_clock = 0; 73 eeprom->reg_chip_select = 1; 74 eeprom->register_write(eeprom); 75 76 /* 77 * kick a pulse. 78 */ 79 eeprom_93cx6_pulse_high(eeprom); 80 eeprom_93cx6_pulse_low(eeprom); 81} 82 83static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom) 84{ 85 /* 86 * Clear chip_select and data_in flags. 87 */ 88 eeprom->register_read(eeprom); 89 eeprom->reg_data_in = 0; 90 eeprom->reg_chip_select = 0; 91 eeprom->register_write(eeprom); 92 93 /* 94 * kick a pulse. 95 */ 96 eeprom_93cx6_pulse_high(eeprom); 97 eeprom_93cx6_pulse_low(eeprom); 98} 99 100static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom, 101 const u16 data, const u16 count) 102{ 103 unsigned int i; 104 105 eeprom->register_read(eeprom); 106 107 /* 108 * Clear data flags. 109 */ 110 eeprom->reg_data_in = 0; 111 eeprom->reg_data_out = 0; 112 113 /* 114 * Start writing all bits. 115 */ 116 for (i = count; i > 0; i--) { 117 /* 118 * Check if this bit needs to be set. 119 */ 120 eeprom->reg_data_in = !!(data & (1 << (i - 1))); 121 122 /* 123 * Write the bit to the eeprom register. 124 */ 125 eeprom->register_write(eeprom); 126 127 /* 128 * Kick a pulse. 129 */ 130 eeprom_93cx6_pulse_high(eeprom); 131 eeprom_93cx6_pulse_low(eeprom); 132 } 133 134 eeprom->reg_data_in = 0; 135 eeprom->register_write(eeprom); 136} 137 138static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom, 139 u16 *data, const u16 count) 140{ 141 unsigned int i; 142 u16 buf = 0; 143 144 eeprom->register_read(eeprom); 145 146 /* 147 * Clear data flags. 148 */ 149 eeprom->reg_data_in = 0; 150 eeprom->reg_data_out = 0; 151 152 /* 153 * Start reading all bits. 154 */ 155 for (i = count; i > 0; i--) { 156 eeprom_93cx6_pulse_high(eeprom); 157 158 eeprom->register_read(eeprom); 159 160 /* 161 * Clear data_in flag. 162 */ 163 eeprom->reg_data_in = 0; 164 165 /* 166 * Read if the bit has been set. 167 */ 168 if (eeprom->reg_data_out) 169 buf |= (1 << (i - 1)); 170 171 eeprom_93cx6_pulse_low(eeprom); 172 } 173 174 *data = buf; 175} 176 177/** 178 * eeprom_93cx6_read - Read multiple words from eeprom 179 * @eeprom: Pointer to eeprom structure 180 * @word: Word index from where we should start reading 181 * @data: target pointer where the information will have to be stored 182 * 183 * This function will read the eeprom data as host-endian word 184 * into the given data pointer. 185 */ 186void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word, 187 u16 *data) 188{ 189 u16 command; 190 191 /* 192 * Initialize the eeprom register 193 */ 194 eeprom_93cx6_startup(eeprom); 195 196 /* 197 * Select the read opcode and the word to be read. 198 */ 199 command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word; 200 eeprom_93cx6_write_bits(eeprom, command, 201 PCI_EEPROM_WIDTH_OPCODE + eeprom->width); 202 203 /* 204 * Read the requested 16 bits. 205 */ 206 eeprom_93cx6_read_bits(eeprom, data, 16); 207 208 /* 209 * Cleanup eeprom register. 210 */ 211 eeprom_93cx6_cleanup(eeprom); 212} 213EXPORT_SYMBOL_GPL(eeprom_93cx6_read); 214 215/** 216 * eeprom_93cx6_multiread - Read multiple words from eeprom 217 * @eeprom: Pointer to eeprom structure 218 * @word: Word index from where we should start reading 219 * @data: target pointer where the information will have to be stored 220 * @words: Number of words that should be read. 221 * 222 * This function will read all requested words from the eeprom, 223 * this is done by calling eeprom_93cx6_read() multiple times. 224 * But with the additional change that while the eeprom_93cx6_read 225 * will return host ordered bytes, this method will return little 226 * endian words. 227 */ 228void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word, 229 __le16 *data, const u16 words) 230{ 231 unsigned int i; 232 u16 tmp; 233 234 for (i = 0; i < words; i++) { 235 tmp = 0; 236 eeprom_93cx6_read(eeprom, word + i, &tmp); 237 data[i] = cpu_to_le16(tmp); 238 } 239} 240EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread); 241