Path: blob/master/drivers/misc/eeprom/eeprom_93cx6.c
15109 views
/*1* Copyright (C) 2004 - 2006 rt2x00 SourceForge Project2* <http://rt2x00.serialmonkey.com>3*4* This program is free software; you can redistribute it and/or modify5* it under the terms of the GNU General Public License as published by6* the Free Software Foundation; either version 2 of the License, or7* (at your option) any later version.8*9* This program is distributed in the hope that it will be useful,10* but WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12* GNU General Public License for more details.13*14* Module: eeprom_93cx615* Abstract: EEPROM reader routines for 93cx6 chipsets.16* Supported chipsets: 93c46 & 93c66.17*/1819#include <linux/kernel.h>20#include <linux/module.h>21#include <linux/delay.h>22#include <linux/eeprom_93cx6.h>2324MODULE_AUTHOR("http://rt2x00.serialmonkey.com");25MODULE_VERSION("1.0");26MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");27MODULE_LICENSE("GPL");2829static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)30{31eeprom->reg_data_clock = 1;32eeprom->register_write(eeprom);3334/*35* Add a short delay for the pulse to work.36* According to the specifications the "maximum minimum"37* time should be 450ns.38*/39ndelay(450);40}4142static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)43{44eeprom->reg_data_clock = 0;45eeprom->register_write(eeprom);4647/*48* Add a short delay for the pulse to work.49* According to the specifications the "maximum minimum"50* time should be 450ns.51*/52ndelay(450);53}5455static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)56{57/*58* Clear all flags, and enable chip select.59*/60eeprom->register_read(eeprom);61eeprom->reg_data_in = 0;62eeprom->reg_data_out = 0;63eeprom->reg_data_clock = 0;64eeprom->reg_chip_select = 1;65eeprom->register_write(eeprom);6667/*68* kick a pulse.69*/70eeprom_93cx6_pulse_high(eeprom);71eeprom_93cx6_pulse_low(eeprom);72}7374static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)75{76/*77* Clear chip_select and data_in flags.78*/79eeprom->register_read(eeprom);80eeprom->reg_data_in = 0;81eeprom->reg_chip_select = 0;82eeprom->register_write(eeprom);8384/*85* kick a pulse.86*/87eeprom_93cx6_pulse_high(eeprom);88eeprom_93cx6_pulse_low(eeprom);89}9091static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,92const u16 data, const u16 count)93{94unsigned int i;9596eeprom->register_read(eeprom);9798/*99* Clear data flags.100*/101eeprom->reg_data_in = 0;102eeprom->reg_data_out = 0;103104/*105* Start writing all bits.106*/107for (i = count; i > 0; i--) {108/*109* Check if this bit needs to be set.110*/111eeprom->reg_data_in = !!(data & (1 << (i - 1)));112113/*114* Write the bit to the eeprom register.115*/116eeprom->register_write(eeprom);117118/*119* Kick a pulse.120*/121eeprom_93cx6_pulse_high(eeprom);122eeprom_93cx6_pulse_low(eeprom);123}124125eeprom->reg_data_in = 0;126eeprom->register_write(eeprom);127}128129static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,130u16 *data, const u16 count)131{132unsigned int i;133u16 buf = 0;134135eeprom->register_read(eeprom);136137/*138* Clear data flags.139*/140eeprom->reg_data_in = 0;141eeprom->reg_data_out = 0;142143/*144* Start reading all bits.145*/146for (i = count; i > 0; i--) {147eeprom_93cx6_pulse_high(eeprom);148149eeprom->register_read(eeprom);150151/*152* Clear data_in flag.153*/154eeprom->reg_data_in = 0;155156/*157* Read if the bit has been set.158*/159if (eeprom->reg_data_out)160buf |= (1 << (i - 1));161162eeprom_93cx6_pulse_low(eeprom);163}164165*data = buf;166}167168/**169* eeprom_93cx6_read - Read multiple words from eeprom170* @eeprom: Pointer to eeprom structure171* @word: Word index from where we should start reading172* @data: target pointer where the information will have to be stored173*174* This function will read the eeprom data as host-endian word175* into the given data pointer.176*/177void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,178u16 *data)179{180u16 command;181182/*183* Initialize the eeprom register184*/185eeprom_93cx6_startup(eeprom);186187/*188* Select the read opcode and the word to be read.189*/190command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;191eeprom_93cx6_write_bits(eeprom, command,192PCI_EEPROM_WIDTH_OPCODE + eeprom->width);193194/*195* Read the requested 16 bits.196*/197eeprom_93cx6_read_bits(eeprom, data, 16);198199/*200* Cleanup eeprom register.201*/202eeprom_93cx6_cleanup(eeprom);203}204EXPORT_SYMBOL_GPL(eeprom_93cx6_read);205206/**207* eeprom_93cx6_multiread - Read multiple words from eeprom208* @eeprom: Pointer to eeprom structure209* @word: Word index from where we should start reading210* @data: target pointer where the information will have to be stored211* @words: Number of words that should be read.212*213* This function will read all requested words from the eeprom,214* this is done by calling eeprom_93cx6_read() multiple times.215* But with the additional change that while the eeprom_93cx6_read216* will return host ordered bytes, this method will return little217* endian words.218*/219void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,220__le16 *data, const u16 words)221{222unsigned int i;223u16 tmp;224225for (i = 0; i < words; i++) {226tmp = 0;227eeprom_93cx6_read(eeprom, word + i, &tmp);228data[i] = cpu_to_le16(tmp);229}230}231EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);232233234235