* [PATCH 1/2] Add 93cx6 eeprom library
@ 2007-05-07 7:46 Michael Wu
[not found] ` <200705070346.04982.flamingice-R9e9/4HEdknk1uMJSBkQmQ@public.gmane.org>
2007-05-07 14:27 ` Ben Dooks
0 siblings, 2 replies; 5+ messages in thread
From: Michael Wu @ 2007-05-07 7:46 UTC (permalink / raw)
To: David Miller
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, John Linville, Ivo van Doorn,
Jeff Garzik
From: Ivo van Doorn <ivdoorn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
This patch adds a library for reading from and writing to 93cx6 eeproms.
Signed-off-by: Michael Wu <flamingice-R9e9/4HEdknk1uMJSBkQmQ@public.gmane.org>
---
drivers/misc/Kconfig | 6 +
drivers/misc/Makefile | 1
drivers/misc/eeprom_93cx6.c | 347 ++++++++++++++++++++++++++++++++++++++++++
include/linux/eeprom_93cx6.h | 77 +++++++++
4 files changed, 431 insertions(+), 0 deletions(-)
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a3c525b..607a180 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -178,4 +178,10 @@ config THINKPAD_ACPI_BAY
If you are not sure, say Y here.
+config EEPROM_93CX6
+ tristate "EEPROM 93CX6 support"
+ ---help---
+ This is a driver for the EEPROM chipsets 93c46 and 93c66.
+ The driver supports both read as well as write commands.
+
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index e325164..42b34a9 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_TIFM_7XX1) += tifm_7
obj-$(CONFIG_SGI_IOC4) += ioc4.o
obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
+obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
new file mode 100644
index 0000000..a948ddc
--- /dev/null
+++ b/drivers/misc/eeprom_93cx6.c
@@ -0,0 +1,347 @@
+/*
+ Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ Module: eeprom_93cx6
+ Abstract: EEPROM reader routines for 93cx6 chipsets.
+ Supported chipsets: 93c46 & 93c66.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/delay.h>
+#include <linux/eeprom_93cx6.h>
+
+MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
+MODULE_VERSION("1.0");
+MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
+MODULE_LICENSE("GPL");
+
+static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
+{
+ eeprom->reg_data_clock = 1;
+ eeprom->register_write(eeprom);
+ udelay(1);
+}
+
+static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
+{
+ eeprom->reg_data_clock = 0;
+ eeprom->register_write(eeprom);
+ udelay(1);
+}
+
+static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
+{
+ /*
+ * Clear all flags, and enable chip select.
+ */
+ eeprom->register_read(eeprom);
+ eeprom->reg_data_in = 0;
+ eeprom->reg_data_out = 0;
+ eeprom->reg_data_clock = 0;
+ eeprom->reg_chip_select = 1;
+ eeprom->register_write(eeprom);
+
+ /*
+ * kick a pulse.
+ */
+ eeprom_93cx6_pulse_high(eeprom);
+ eeprom_93cx6_pulse_low(eeprom);
+}
+
+static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)
+{
+ /*
+ * Clear chip_select and data_in flags.
+ */
+ eeprom->register_read(eeprom);
+ eeprom->reg_data_in = 0;
+ eeprom->reg_chip_select = 0;
+ eeprom->register_write(eeprom);
+
+ /*
+ * kick a pulse.
+ */
+ eeprom_93cx6_pulse_high(eeprom);
+ eeprom_93cx6_pulse_low(eeprom);
+}
+
+static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
+ const u16 data, const u16 count)
+{
+ unsigned int i;
+
+ eeprom->register_read(eeprom);
+
+ /*
+ * Clear data flags.
+ */
+ eeprom->reg_data_in = 0;
+ eeprom->reg_data_out = 0;
+
+ /*
+ * Start writing all bits.
+ */
+ for (i = count; i > 0; i--) {
+ /*
+ * Check if this bit needs to be set.
+ */
+ eeprom->reg_data_in = !!(data & (1 << (i - 1)));
+
+ /*
+ * Write the bit to the eeprom register.
+ */
+ eeprom->register_write(eeprom);
+
+ /*
+ * Kick a pulse.
+ */
+ eeprom_93cx6_pulse_high(eeprom);
+ eeprom_93cx6_pulse_low(eeprom);
+ }
+
+ eeprom->reg_data_in = 0;
+ eeprom->register_write(eeprom);
+}
+
+static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
+ u16 *data, const u16 count)
+{
+ unsigned int i;
+ u16 buf = 0;
+
+ eeprom->register_read(eeprom);
+
+ /*
+ * Clear data flags.
+ */
+ eeprom->reg_data_in = 0;
+ eeprom->reg_data_out = 0;
+
+ /*
+ * Start reading all bits.
+ */
+ for (i = count; i > 0; i--) {
+ eeprom_93cx6_pulse_high(eeprom);
+
+ eeprom->register_read(eeprom);
+
+ /*
+ * Clear data_in flag.
+ */
+ eeprom->reg_data_in = 0;
+
+ /*
+ * Read if the bit has been set.
+ */
+ if (eeprom->reg_data_out)
+ buf |= (1 << (i - 1));
+
+ eeprom_93cx6_pulse_low(eeprom);
+ }
+
+ *data = buf;
+}
+
+static void eeprom_93cx6_ewen(struct eeprom_93cx6 *eeprom)
+{
+ /*
+ * Initialize the eeprom register
+ */
+ eeprom_93cx6_startup(eeprom);
+
+ /*
+ * Select the read opcode and the word to be read.
+ */
+ eeprom_93cx6_write_bits(eeprom, PCI_EEPROM_EWEN_OPCODE, 5);
+ eeprom_93cx6_write_bits(eeprom, 0, 6);
+
+ /*
+ * Cleanup eeprom register.
+ */
+ eeprom_93cx6_cleanup(eeprom);
+}
+
+static void eeprom_93cx6_ewds(struct eeprom_93cx6 *eeprom)
+{
+ /*
+ * Initialize the eeprom register
+ */
+ eeprom_93cx6_startup(eeprom);
+
+ /*
+ * Select the read opcode and the word to be read.
+ */
+ eeprom_93cx6_write_bits(eeprom, PCI_EEPROM_EWDS_OPCODE, 5);
+ eeprom_93cx6_write_bits(eeprom, 0, 6);
+
+ /*
+ * Cleanup eeprom register.
+ */
+ eeprom_93cx6_cleanup(eeprom);
+}
+
+/**
+ * eeprom_93cx6_read - Read multiple words from eeprom
+ * @eeprom: Pointer to eeprom structure
+ * @word: Word index from where we should start reading
+ * @data: target pointer where the information will have to be stored
+ *
+ * This function will read the eeprom data as host-endian word
+ * into the given data pointer.
+ */
+void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
+ u16 *data)
+{
+ u16 command;
+
+ /*
+ * Initialize the eeprom register
+ */
+ eeprom_93cx6_startup(eeprom);
+
+ /*
+ * Select the read opcode and the word to be read.
+ */
+ command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
+ eeprom_93cx6_write_bits(eeprom, command,
+ PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
+
+ /*
+ * Read the requested 16 bits.
+ */
+ eeprom_93cx6_read_bits(eeprom, data, 16);
+
+ /*
+ * Cleanup eeprom register.
+ */
+ eeprom_93cx6_cleanup(eeprom);
+}
+EXPORT_SYMBOL_GPL(eeprom_93cx6_read);
+
+/**
+ * eeprom_93cx6_multiread - Read multiple words from eeprom
+ * @eeprom: Pointer to eeprom structure
+ * @word: Word index from where we should start reading
+ * @data: target pointer where the information will have to be stored
+ * @words: Number of words that should be read.
+ *
+ * This function will read all requested words from the eeprom,
+ * this is done by calling eeprom_93cx6_read() multiple times.
+ * But with the additional change that while the eeprom_93cx6_read
+ * will return host ordered bytes, this method will return little
+ * endian words.
+ */
+void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
+ __le16 *data, const u16 words)
+{
+ unsigned int i;
+ u16 tmp;
+
+ for (i = 0; i < words; i++) {
+ tmp = 0;
+ eeprom_93cx6_read(eeprom, word + i, &tmp);
+ data[i] = cpu_to_le16(tmp);
+ }
+}
+EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
+
+/**
+ * eeprom_93cx6_write - Write multiple words to the eeprom
+ * @eeprom: Pointer to eeprom structure
+ * @word: Word index from where we should start writing
+ * @data: Data that will be written
+ *
+ * This function will write the eeprom data as host-endian word
+ * from the given data pointer.
+ */
+void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, const u8 word,
+ u16 data)
+{
+ u16 command;
+
+ /*
+ * select the ewen opcode.
+ */
+ eeprom_93cx6_ewen(eeprom);
+
+ /*
+ * Initialize the eeprom register
+ */
+ eeprom_93cx6_startup(eeprom);
+
+ /*
+ * Select the write opcode and the word to be read.
+ */
+ command = (PCI_EEPROM_WRITE_OPCODE << eeprom->width) | word;
+ eeprom_93cx6_write_bits(eeprom, command,
+ PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
+
+ /*
+ * Write the requested 16 bits.
+ */
+ eeprom_93cx6_write_bits(eeprom, data, 16);
+
+ /*
+ * Cleanup eeprom register.
+ */
+ eeprom_93cx6_cleanup(eeprom);
+
+ /*
+ * Take a short break.
+ */
+ msleep(10000);
+
+ /*
+ * select the ewen opcode.
+ */
+ eeprom_93cx6_ewds(eeprom);
+
+ /*
+ * Cleanup eeprom register.
+ */
+ eeprom_93cx6_cleanup(eeprom);
+}
+EXPORT_SYMBOL_GPL(eeprom_93cx6_write);
+
+
+/**
+ * eeprom_93cx6_multiwrite - Write multiple words to the eeprom
+ * @eeprom: Pointer to eeprom structure
+ * @word: Word index from where we should start writing
+ * @data: Pointer where the information will be read from
+ * @words: Number of words that should be written.
+ *
+ * This function will write all requested words to the eeprom,
+ * this is done by calling eeprom_93cx6_write() multiple times.
+ * This method accepts little endian data, so it will first be
+ * converted into host endian.
+ */
+void eeprom_93cx6_multiwrite(struct eeprom_93cx6 *eeprom, const u8 word,
+ __le16 *data, const u16 words)
+{
+ unsigned int i;
+
+ for (i = 0; i < words; i++)
+ eeprom_93cx6_write(eeprom, word + i, le16_to_cpu(data[i]));
+}
+EXPORT_SYMBOL_GPL(eeprom_93cx6_multiwrite);
diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h
new file mode 100644
index 0000000..4b9be59
--- /dev/null
+++ b/include/linux/eeprom_93cx6.h
@@ -0,0 +1,77 @@
+/*
+ Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ Module: eeprom_93cx6
+ Abstract: EEPROM reader datastructures for 93cx6 chipsets.
+ Supported chipsets: 93c46 & 93c66.
+ */
+
+/*
+ * EEPROM operation defines.
+ */
+#define PCI_EEPROM_WIDTH_93C46 6
+#define PCI_EEPROM_WIDTH_93C66 8
+#define PCI_EEPROM_WIDTH_OPCODE 3
+#define PCI_EEPROM_WRITE_OPCODE 0x05
+#define PCI_EEPROM_READ_OPCODE 0x06
+#define PCI_EEPROM_EWDS_OPCODE 0x10
+#define PCI_EEPROM_EWEN_OPCODE 0x13
+
+/**
+ * struct eeprom_93cx6 - control structure for setting the commands
+ * for reading the eeprom data.
+ * @data: private pointer for the driver.
+ * @register_read(struct eeprom_93cx6 *eeprom): handler to
+ * read the eeprom register, this function should set all reg_* fields.
+ * @register_write(struct eeprom_93cx6 *eeprom): handler to
+ * write to the eeprom register by using all reg_* fields.
+ * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines
+ * @reg_data_in: register field to indicate data input
+ * @reg_data_out: register field to indicate data output
+ * @reg_data_clock: register field to set the data clock
+ * @reg_chip_select: register field to set the chip select
+ *
+ * This structure is used for the communication between the driver
+ * and the eeprom_93cx6 handlers for reading the eeprom.
+ */
+struct eeprom_93cx6 {
+ void *data;
+
+ void (*register_read)(struct eeprom_93cx6 *eeprom);
+ void (*register_write)(struct eeprom_93cx6 *eeprom);
+
+ int width;
+
+ char reg_data_in;
+ char reg_data_out;
+ char reg_data_clock;
+ char reg_chip_select;
+};
+
+extern void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom,
+ const u8 word, u16 *data);
+extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom,
+ const u8 word, __le16 *data, const u16 words);
+
+extern void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom,
+ const u8 word, u16 data);
+extern void eeprom_93cx6_multiwrite(struct eeprom_93cx6 *eeprom,
+ const u8 word, __le16 *data, const u16 words);
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] Add 93cx6 eeprom library
[not found] ` <200705070346.04982.flamingice-R9e9/4HEdknk1uMJSBkQmQ@public.gmane.org>
@ 2007-05-07 7:53 ` Ivo van Doorn
0 siblings, 0 replies; 5+ messages in thread
From: Ivo van Doorn @ 2007-05-07 7:53 UTC (permalink / raw)
To: Michael Wu
Cc: David Miller, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, John Linville, Jeff Garzik
On Monday 07 May 2007 09:46, Michael Wu wrote:
> From: Ivo van Doorn <ivdoorn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> This patch adds a library for reading from and writing to 93cx6 eeproms.
>
> Signed-off-by: Michael Wu <flamingice-R9e9/4HEdknk1uMJSBkQmQ@public.gmane.org>
Signed-off-by: Ivo van Doorn <IvDoorn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>
> drivers/misc/Kconfig | 6 +
> drivers/misc/Makefile | 1
> drivers/misc/eeprom_93cx6.c | 347 ++++++++++++++++++++++++++++++++++++++++++
> include/linux/eeprom_93cx6.h | 77 +++++++++
> 4 files changed, 431 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index a3c525b..607a180 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -178,4 +178,10 @@ config THINKPAD_ACPI_BAY
>
> If you are not sure, say Y here.
>
> +config EEPROM_93CX6
> + tristate "EEPROM 93CX6 support"
> + ---help---
> + This is a driver for the EEPROM chipsets 93c46 and 93c66.
> + The driver supports both read as well as write commands.
> +
> endmenu
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index e325164..42b34a9 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -13,3 +13,4 @@ obj-$(CONFIG_TIFM_7XX1) += tifm_7
> obj-$(CONFIG_SGI_IOC4) += ioc4.o
> obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
> obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
> +obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
> diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
> new file mode 100644
> index 0000000..a948ddc
> --- /dev/null
> +++ b/drivers/misc/eeprom_93cx6.c
> @@ -0,0 +1,347 @@
> +/*
> + Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
> + <http://rt2x00.serialmonkey.com>
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 2 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program; if not, write to the
> + Free Software Foundation, Inc.,
> + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + */
> +
> +/*
> + Module: eeprom_93cx6
> + Abstract: EEPROM reader routines for 93cx6 chipsets.
> + Supported chipsets: 93c46 & 93c66.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/version.h>
> +#include <linux/delay.h>
> +#include <linux/eeprom_93cx6.h>
> +
> +MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
> +MODULE_VERSION("1.0");
> +MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
> +MODULE_LICENSE("GPL");
> +
> +static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
> +{
> + eeprom->reg_data_clock = 1;
> + eeprom->register_write(eeprom);
> + udelay(1);
> +}
> +
> +static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
> +{
> + eeprom->reg_data_clock = 0;
> + eeprom->register_write(eeprom);
> + udelay(1);
> +}
> +
> +static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
> +{
> + /*
> + * Clear all flags, and enable chip select.
> + */
> + eeprom->register_read(eeprom);
> + eeprom->reg_data_in = 0;
> + eeprom->reg_data_out = 0;
> + eeprom->reg_data_clock = 0;
> + eeprom->reg_chip_select = 1;
> + eeprom->register_write(eeprom);
> +
> + /*
> + * kick a pulse.
> + */
> + eeprom_93cx6_pulse_high(eeprom);
> + eeprom_93cx6_pulse_low(eeprom);
> +}
> +
> +static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)
> +{
> + /*
> + * Clear chip_select and data_in flags.
> + */
> + eeprom->register_read(eeprom);
> + eeprom->reg_data_in = 0;
> + eeprom->reg_chip_select = 0;
> + eeprom->register_write(eeprom);
> +
> + /*
> + * kick a pulse.
> + */
> + eeprom_93cx6_pulse_high(eeprom);
> + eeprom_93cx6_pulse_low(eeprom);
> +}
> +
> +static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
> + const u16 data, const u16 count)
> +{
> + unsigned int i;
> +
> + eeprom->register_read(eeprom);
> +
> + /*
> + * Clear data flags.
> + */
> + eeprom->reg_data_in = 0;
> + eeprom->reg_data_out = 0;
> +
> + /*
> + * Start writing all bits.
> + */
> + for (i = count; i > 0; i--) {
> + /*
> + * Check if this bit needs to be set.
> + */
> + eeprom->reg_data_in = !!(data & (1 << (i - 1)));
> +
> + /*
> + * Write the bit to the eeprom register.
> + */
> + eeprom->register_write(eeprom);
> +
> + /*
> + * Kick a pulse.
> + */
> + eeprom_93cx6_pulse_high(eeprom);
> + eeprom_93cx6_pulse_low(eeprom);
> + }
> +
> + eeprom->reg_data_in = 0;
> + eeprom->register_write(eeprom);
> +}
> +
> +static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
> + u16 *data, const u16 count)
> +{
> + unsigned int i;
> + u16 buf = 0;
> +
> + eeprom->register_read(eeprom);
> +
> + /*
> + * Clear data flags.
> + */
> + eeprom->reg_data_in = 0;
> + eeprom->reg_data_out = 0;
> +
> + /*
> + * Start reading all bits.
> + */
> + for (i = count; i > 0; i--) {
> + eeprom_93cx6_pulse_high(eeprom);
> +
> + eeprom->register_read(eeprom);
> +
> + /*
> + * Clear data_in flag.
> + */
> + eeprom->reg_data_in = 0;
> +
> + /*
> + * Read if the bit has been set.
> + */
> + if (eeprom->reg_data_out)
> + buf |= (1 << (i - 1));
> +
> + eeprom_93cx6_pulse_low(eeprom);
> + }
> +
> + *data = buf;
> +}
> +
> +static void eeprom_93cx6_ewen(struct eeprom_93cx6 *eeprom)
> +{
> + /*
> + * Initialize the eeprom register
> + */
> + eeprom_93cx6_startup(eeprom);
> +
> + /*
> + * Select the read opcode and the word to be read.
> + */
> + eeprom_93cx6_write_bits(eeprom, PCI_EEPROM_EWEN_OPCODE, 5);
> + eeprom_93cx6_write_bits(eeprom, 0, 6);
> +
> + /*
> + * Cleanup eeprom register.
> + */
> + eeprom_93cx6_cleanup(eeprom);
> +}
> +
> +static void eeprom_93cx6_ewds(struct eeprom_93cx6 *eeprom)
> +{
> + /*
> + * Initialize the eeprom register
> + */
> + eeprom_93cx6_startup(eeprom);
> +
> + /*
> + * Select the read opcode and the word to be read.
> + */
> + eeprom_93cx6_write_bits(eeprom, PCI_EEPROM_EWDS_OPCODE, 5);
> + eeprom_93cx6_write_bits(eeprom, 0, 6);
> +
> + /*
> + * Cleanup eeprom register.
> + */
> + eeprom_93cx6_cleanup(eeprom);
> +}
> +
> +/**
> + * eeprom_93cx6_read - Read multiple words from eeprom
> + * @eeprom: Pointer to eeprom structure
> + * @word: Word index from where we should start reading
> + * @data: target pointer where the information will have to be stored
> + *
> + * This function will read the eeprom data as host-endian word
> + * into the given data pointer.
> + */
> +void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
> + u16 *data)
> +{
> + u16 command;
> +
> + /*
> + * Initialize the eeprom register
> + */
> + eeprom_93cx6_startup(eeprom);
> +
> + /*
> + * Select the read opcode and the word to be read.
> + */
> + command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
> + eeprom_93cx6_write_bits(eeprom, command,
> + PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
> +
> + /*
> + * Read the requested 16 bits.
> + */
> + eeprom_93cx6_read_bits(eeprom, data, 16);
> +
> + /*
> + * Cleanup eeprom register.
> + */
> + eeprom_93cx6_cleanup(eeprom);
> +}
> +EXPORT_SYMBOL_GPL(eeprom_93cx6_read);
> +
> +/**
> + * eeprom_93cx6_multiread - Read multiple words from eeprom
> + * @eeprom: Pointer to eeprom structure
> + * @word: Word index from where we should start reading
> + * @data: target pointer where the information will have to be stored
> + * @words: Number of words that should be read.
> + *
> + * This function will read all requested words from the eeprom,
> + * this is done by calling eeprom_93cx6_read() multiple times.
> + * But with the additional change that while the eeprom_93cx6_read
> + * will return host ordered bytes, this method will return little
> + * endian words.
> + */
> +void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
> + __le16 *data, const u16 words)
> +{
> + unsigned int i;
> + u16 tmp;
> +
> + for (i = 0; i < words; i++) {
> + tmp = 0;
> + eeprom_93cx6_read(eeprom, word + i, &tmp);
> + data[i] = cpu_to_le16(tmp);
> + }
> +}
> +EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
> +
> +/**
> + * eeprom_93cx6_write - Write multiple words to the eeprom
> + * @eeprom: Pointer to eeprom structure
> + * @word: Word index from where we should start writing
> + * @data: Data that will be written
> + *
> + * This function will write the eeprom data as host-endian word
> + * from the given data pointer.
> + */
> +void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, const u8 word,
> + u16 data)
> +{
> + u16 command;
> +
> + /*
> + * select the ewen opcode.
> + */
> + eeprom_93cx6_ewen(eeprom);
> +
> + /*
> + * Initialize the eeprom register
> + */
> + eeprom_93cx6_startup(eeprom);
> +
> + /*
> + * Select the write opcode and the word to be read.
> + */
> + command = (PCI_EEPROM_WRITE_OPCODE << eeprom->width) | word;
> + eeprom_93cx6_write_bits(eeprom, command,
> + PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
> +
> + /*
> + * Write the requested 16 bits.
> + */
> + eeprom_93cx6_write_bits(eeprom, data, 16);
> +
> + /*
> + * Cleanup eeprom register.
> + */
> + eeprom_93cx6_cleanup(eeprom);
> +
> + /*
> + * Take a short break.
> + */
> + msleep(10000);
> +
> + /*
> + * select the ewen opcode.
> + */
> + eeprom_93cx6_ewds(eeprom);
> +
> + /*
> + * Cleanup eeprom register.
> + */
> + eeprom_93cx6_cleanup(eeprom);
> +}
> +EXPORT_SYMBOL_GPL(eeprom_93cx6_write);
> +
> +
> +/**
> + * eeprom_93cx6_multiwrite - Write multiple words to the eeprom
> + * @eeprom: Pointer to eeprom structure
> + * @word: Word index from where we should start writing
> + * @data: Pointer where the information will be read from
> + * @words: Number of words that should be written.
> + *
> + * This function will write all requested words to the eeprom,
> + * this is done by calling eeprom_93cx6_write() multiple times.
> + * This method accepts little endian data, so it will first be
> + * converted into host endian.
> + */
> +void eeprom_93cx6_multiwrite(struct eeprom_93cx6 *eeprom, const u8 word,
> + __le16 *data, const u16 words)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < words; i++)
> + eeprom_93cx6_write(eeprom, word + i, le16_to_cpu(data[i]));
> +}
> +EXPORT_SYMBOL_GPL(eeprom_93cx6_multiwrite);
> diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h
> new file mode 100644
> index 0000000..4b9be59
> --- /dev/null
> +++ b/include/linux/eeprom_93cx6.h
> @@ -0,0 +1,77 @@
> +/*
> + Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
> + <http://rt2x00.serialmonkey.com>
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 2 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program; if not, write to the
> + Free Software Foundation, Inc.,
> + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + */
> +
> +/*
> + Module: eeprom_93cx6
> + Abstract: EEPROM reader datastructures for 93cx6 chipsets.
> + Supported chipsets: 93c46 & 93c66.
> + */
> +
> +/*
> + * EEPROM operation defines.
> + */
> +#define PCI_EEPROM_WIDTH_93C46 6
> +#define PCI_EEPROM_WIDTH_93C66 8
> +#define PCI_EEPROM_WIDTH_OPCODE 3
> +#define PCI_EEPROM_WRITE_OPCODE 0x05
> +#define PCI_EEPROM_READ_OPCODE 0x06
> +#define PCI_EEPROM_EWDS_OPCODE 0x10
> +#define PCI_EEPROM_EWEN_OPCODE 0x13
> +
> +/**
> + * struct eeprom_93cx6 - control structure for setting the commands
> + * for reading the eeprom data.
> + * @data: private pointer for the driver.
> + * @register_read(struct eeprom_93cx6 *eeprom): handler to
> + * read the eeprom register, this function should set all reg_* fields.
> + * @register_write(struct eeprom_93cx6 *eeprom): handler to
> + * write to the eeprom register by using all reg_* fields.
> + * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines
> + * @reg_data_in: register field to indicate data input
> + * @reg_data_out: register field to indicate data output
> + * @reg_data_clock: register field to set the data clock
> + * @reg_chip_select: register field to set the chip select
> + *
> + * This structure is used for the communication between the driver
> + * and the eeprom_93cx6 handlers for reading the eeprom.
> + */
> +struct eeprom_93cx6 {
> + void *data;
> +
> + void (*register_read)(struct eeprom_93cx6 *eeprom);
> + void (*register_write)(struct eeprom_93cx6 *eeprom);
> +
> + int width;
> +
> + char reg_data_in;
> + char reg_data_out;
> + char reg_data_clock;
> + char reg_chip_select;
> +};
> +
> +extern void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom,
> + const u8 word, u16 *data);
> +extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom,
> + const u8 word, __le16 *data, const u16 words);
> +
> +extern void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom,
> + const u8 word, u16 data);
> +extern void eeprom_93cx6_multiwrite(struct eeprom_93cx6 *eeprom,
> + const u8 word, __le16 *data, const u16 words);
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] Add 93cx6 eeprom library
2007-05-07 7:46 [PATCH 1/2] Add 93cx6 eeprom library Michael Wu
[not found] ` <200705070346.04982.flamingice-R9e9/4HEdknk1uMJSBkQmQ@public.gmane.org>
@ 2007-05-07 14:27 ` Ben Dooks
[not found] ` <20070507142715.GB32546-elnMNo+KYs3pIgCt6eIbzw@public.gmane.org>
1 sibling, 1 reply; 5+ messages in thread
From: Ben Dooks @ 2007-05-07 14:27 UTC (permalink / raw)
To: Michael Wu
Cc: David Miller, linux-wireless, netdev, John Linville,
Ivo van Doorn, Jeff Garzik
On Mon, May 07, 2007 at 03:46:04AM -0400, Michael Wu wrote:
> From: Ivo van Doorn <ivdoorn@gmail.com>
>
> This patch adds a library for reading from and writing to 93cx6 eeproms.
This looks remarkably like an SPI device, why not use the
spi framework to drive this?
> Signed-off-by: Michael Wu <flamingice@sourmilk.net>
> ---
>
> drivers/misc/Kconfig | 6 +
> drivers/misc/Makefile | 1
> drivers/misc/eeprom_93cx6.c | 347 ++++++++++++++++++++++++++++++++++++++++++
> include/linux/eeprom_93cx6.h | 77 +++++++++
> 4 files changed, 431 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index a3c525b..607a180 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -178,4 +178,10 @@ config THINKPAD_ACPI_BAY
>
> If you are not sure, say Y here.
>
> +config EEPROM_93CX6
> + tristate "EEPROM 93CX6 support"
> + ---help---
> + This is a driver for the EEPROM chipsets 93c46 and 93c66.
> + The driver supports both read as well as write commands.
> +
> endmenu
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index e325164..42b34a9 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -13,3 +13,4 @@ obj-$(CONFIG_TIFM_7XX1) += tifm_7
> obj-$(CONFIG_SGI_IOC4) += ioc4.o
> obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
> obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
> +obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
> diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
> new file mode 100644
> index 0000000..a948ddc
> --- /dev/null
> +++ b/drivers/misc/eeprom_93cx6.c
> @@ -0,0 +1,347 @@
> +/*
> + Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
> + <http://rt2x00.serialmonkey.com>
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 2 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program; if not, write to the
> + Free Software Foundation, Inc.,
> + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + */
> +
> +/*
> + Module: eeprom_93cx6
> + Abstract: EEPROM reader routines for 93cx6 chipsets.
> + Supported chipsets: 93c46 & 93c66.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/version.h>
> +#include <linux/delay.h>
> +#include <linux/eeprom_93cx6.h>
> +
> +MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
> +MODULE_VERSION("1.0");
> +MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
> +MODULE_LICENSE("GPL");
> +
> +static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
> +{
> + eeprom->reg_data_clock = 1;
> + eeprom->register_write(eeprom);
> + udelay(1);
> +}
> +
> +static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
> +{
> + eeprom->reg_data_clock = 0;
> + eeprom->register_write(eeprom);
> + udelay(1);
> +}
> +
> +static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
> +{
> + /*
> + * Clear all flags, and enable chip select.
> + */
> + eeprom->register_read(eeprom);
> + eeprom->reg_data_in = 0;
> + eeprom->reg_data_out = 0;
> + eeprom->reg_data_clock = 0;
> + eeprom->reg_chip_select = 1;
> + eeprom->register_write(eeprom);
> +
> + /*
> + * kick a pulse.
> + */
> + eeprom_93cx6_pulse_high(eeprom);
> + eeprom_93cx6_pulse_low(eeprom);
> +}
> +
> +static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)
> +{
> + /*
> + * Clear chip_select and data_in flags.
> + */
> + eeprom->register_read(eeprom);
> + eeprom->reg_data_in = 0;
> + eeprom->reg_chip_select = 0;
> + eeprom->register_write(eeprom);
> +
> + /*
> + * kick a pulse.
> + */
> + eeprom_93cx6_pulse_high(eeprom);
> + eeprom_93cx6_pulse_low(eeprom);
> +}
> +
> +static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
> + const u16 data, const u16 count)
> +{
> + unsigned int i;
> +
> + eeprom->register_read(eeprom);
> +
> + /*
> + * Clear data flags.
> + */
> + eeprom->reg_data_in = 0;
> + eeprom->reg_data_out = 0;
> +
> + /*
> + * Start writing all bits.
> + */
> + for (i = count; i > 0; i--) {
> + /*
> + * Check if this bit needs to be set.
> + */
> + eeprom->reg_data_in = !!(data & (1 << (i - 1)));
> +
> + /*
> + * Write the bit to the eeprom register.
> + */
> + eeprom->register_write(eeprom);
> +
> + /*
> + * Kick a pulse.
> + */
> + eeprom_93cx6_pulse_high(eeprom);
> + eeprom_93cx6_pulse_low(eeprom);
> + }
> +
> + eeprom->reg_data_in = 0;
> + eeprom->register_write(eeprom);
> +}
> +
> +static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
> + u16 *data, const u16 count)
> +{
> + unsigned int i;
> + u16 buf = 0;
> +
> + eeprom->register_read(eeprom);
> +
> + /*
> + * Clear data flags.
> + */
> + eeprom->reg_data_in = 0;
> + eeprom->reg_data_out = 0;
> +
> + /*
> + * Start reading all bits.
> + */
> + for (i = count; i > 0; i--) {
> + eeprom_93cx6_pulse_high(eeprom);
> +
> + eeprom->register_read(eeprom);
> +
> + /*
> + * Clear data_in flag.
> + */
> + eeprom->reg_data_in = 0;
> +
> + /*
> + * Read if the bit has been set.
> + */
> + if (eeprom->reg_data_out)
> + buf |= (1 << (i - 1));
> +
> + eeprom_93cx6_pulse_low(eeprom);
> + }
> +
> + *data = buf;
> +}
> +
> +static void eeprom_93cx6_ewen(struct eeprom_93cx6 *eeprom)
> +{
> + /*
> + * Initialize the eeprom register
> + */
> + eeprom_93cx6_startup(eeprom);
> +
> + /*
> + * Select the read opcode and the word to be read.
> + */
> + eeprom_93cx6_write_bits(eeprom, PCI_EEPROM_EWEN_OPCODE, 5);
> + eeprom_93cx6_write_bits(eeprom, 0, 6);
> +
> + /*
> + * Cleanup eeprom register.
> + */
> + eeprom_93cx6_cleanup(eeprom);
> +}
> +
> +static void eeprom_93cx6_ewds(struct eeprom_93cx6 *eeprom)
> +{
> + /*
> + * Initialize the eeprom register
> + */
> + eeprom_93cx6_startup(eeprom);
> +
> + /*
> + * Select the read opcode and the word to be read.
> + */
> + eeprom_93cx6_write_bits(eeprom, PCI_EEPROM_EWDS_OPCODE, 5);
> + eeprom_93cx6_write_bits(eeprom, 0, 6);
> +
> + /*
> + * Cleanup eeprom register.
> + */
> + eeprom_93cx6_cleanup(eeprom);
> +}
> +
> +/**
> + * eeprom_93cx6_read - Read multiple words from eeprom
> + * @eeprom: Pointer to eeprom structure
> + * @word: Word index from where we should start reading
> + * @data: target pointer where the information will have to be stored
> + *
> + * This function will read the eeprom data as host-endian word
> + * into the given data pointer.
> + */
> +void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
> + u16 *data)
> +{
> + u16 command;
> +
> + /*
> + * Initialize the eeprom register
> + */
> + eeprom_93cx6_startup(eeprom);
> +
> + /*
> + * Select the read opcode and the word to be read.
> + */
> + command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
> + eeprom_93cx6_write_bits(eeprom, command,
> + PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
> +
> + /*
> + * Read the requested 16 bits.
> + */
> + eeprom_93cx6_read_bits(eeprom, data, 16);
> +
> + /*
> + * Cleanup eeprom register.
> + */
> + eeprom_93cx6_cleanup(eeprom);
> +}
> +EXPORT_SYMBOL_GPL(eeprom_93cx6_read);
> +
> +/**
> + * eeprom_93cx6_multiread - Read multiple words from eeprom
> + * @eeprom: Pointer to eeprom structure
> + * @word: Word index from where we should start reading
> + * @data: target pointer where the information will have to be stored
> + * @words: Number of words that should be read.
> + *
> + * This function will read all requested words from the eeprom,
> + * this is done by calling eeprom_93cx6_read() multiple times.
> + * But with the additional change that while the eeprom_93cx6_read
> + * will return host ordered bytes, this method will return little
> + * endian words.
> + */
> +void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
> + __le16 *data, const u16 words)
> +{
> + unsigned int i;
> + u16 tmp;
> +
> + for (i = 0; i < words; i++) {
> + tmp = 0;
> + eeprom_93cx6_read(eeprom, word + i, &tmp);
> + data[i] = cpu_to_le16(tmp);
> + }
> +}
> +EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
> +
> +/**
> + * eeprom_93cx6_write - Write multiple words to the eeprom
> + * @eeprom: Pointer to eeprom structure
> + * @word: Word index from where we should start writing
> + * @data: Data that will be written
> + *
> + * This function will write the eeprom data as host-endian word
> + * from the given data pointer.
> + */
> +void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, const u8 word,
> + u16 data)
> +{
> + u16 command;
> +
> + /*
> + * select the ewen opcode.
> + */
> + eeprom_93cx6_ewen(eeprom);
> +
> + /*
> + * Initialize the eeprom register
> + */
> + eeprom_93cx6_startup(eeprom);
> +
> + /*
> + * Select the write opcode and the word to be read.
> + */
> + command = (PCI_EEPROM_WRITE_OPCODE << eeprom->width) | word;
> + eeprom_93cx6_write_bits(eeprom, command,
> + PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
> +
> + /*
> + * Write the requested 16 bits.
> + */
> + eeprom_93cx6_write_bits(eeprom, data, 16);
> +
> + /*
> + * Cleanup eeprom register.
> + */
> + eeprom_93cx6_cleanup(eeprom);
> +
> + /*
> + * Take a short break.
> + */
> + msleep(10000);
> +
> + /*
> + * select the ewen opcode.
> + */
> + eeprom_93cx6_ewds(eeprom);
> +
> + /*
> + * Cleanup eeprom register.
> + */
> + eeprom_93cx6_cleanup(eeprom);
> +}
> +EXPORT_SYMBOL_GPL(eeprom_93cx6_write);
> +
> +
> +/**
> + * eeprom_93cx6_multiwrite - Write multiple words to the eeprom
> + * @eeprom: Pointer to eeprom structure
> + * @word: Word index from where we should start writing
> + * @data: Pointer where the information will be read from
> + * @words: Number of words that should be written.
> + *
> + * This function will write all requested words to the eeprom,
> + * this is done by calling eeprom_93cx6_write() multiple times.
> + * This method accepts little endian data, so it will first be
> + * converted into host endian.
> + */
> +void eeprom_93cx6_multiwrite(struct eeprom_93cx6 *eeprom, const u8 word,
> + __le16 *data, const u16 words)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < words; i++)
> + eeprom_93cx6_write(eeprom, word + i, le16_to_cpu(data[i]));
> +}
> +EXPORT_SYMBOL_GPL(eeprom_93cx6_multiwrite);
> diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h
> new file mode 100644
> index 0000000..4b9be59
> --- /dev/null
> +++ b/include/linux/eeprom_93cx6.h
> @@ -0,0 +1,77 @@
> +/*
> + Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
> + <http://rt2x00.serialmonkey.com>
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 2 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program; if not, write to the
> + Free Software Foundation, Inc.,
> + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + */
> +
> +/*
> + Module: eeprom_93cx6
> + Abstract: EEPROM reader datastructures for 93cx6 chipsets.
> + Supported chipsets: 93c46 & 93c66.
> + */
> +
> +/*
> + * EEPROM operation defines.
> + */
> +#define PCI_EEPROM_WIDTH_93C46 6
> +#define PCI_EEPROM_WIDTH_93C66 8
> +#define PCI_EEPROM_WIDTH_OPCODE 3
> +#define PCI_EEPROM_WRITE_OPCODE 0x05
> +#define PCI_EEPROM_READ_OPCODE 0x06
> +#define PCI_EEPROM_EWDS_OPCODE 0x10
> +#define PCI_EEPROM_EWEN_OPCODE 0x13
> +
> +/**
> + * struct eeprom_93cx6 - control structure for setting the commands
> + * for reading the eeprom data.
> + * @data: private pointer for the driver.
> + * @register_read(struct eeprom_93cx6 *eeprom): handler to
> + * read the eeprom register, this function should set all reg_* fields.
> + * @register_write(struct eeprom_93cx6 *eeprom): handler to
> + * write to the eeprom register by using all reg_* fields.
> + * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines
> + * @reg_data_in: register field to indicate data input
> + * @reg_data_out: register field to indicate data output
> + * @reg_data_clock: register field to set the data clock
> + * @reg_chip_select: register field to set the chip select
> + *
> + * This structure is used for the communication between the driver
> + * and the eeprom_93cx6 handlers for reading the eeprom.
> + */
> +struct eeprom_93cx6 {
> + void *data;
> +
> + void (*register_read)(struct eeprom_93cx6 *eeprom);
> + void (*register_write)(struct eeprom_93cx6 *eeprom);
> +
> + int width;
> +
> + char reg_data_in;
> + char reg_data_out;
> + char reg_data_clock;
> + char reg_chip_select;
> +};
> +
> +extern void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom,
> + const u8 word, u16 *data);
> +extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom,
> + const u8 word, __le16 *data, const u16 words);
> +
> +extern void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom,
> + const u8 word, u16 data);
> +extern void eeprom_93cx6_multiwrite(struct eeprom_93cx6 *eeprom,
> + const u8 word, __le16 *data, const u16 words);
>
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Ben (ben@fluff.org, http://www.fluff.org/)
'a smiley only costs 4 bytes'
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] Add 93cx6 eeprom library
[not found] ` <20070507142715.GB32546-elnMNo+KYs3pIgCt6eIbzw@public.gmane.org>
@ 2007-05-07 15:34 ` John W. Linville
2007-05-07 15:40 ` Michael Wu
1 sibling, 0 replies; 5+ messages in thread
From: John W. Linville @ 2007-05-07 15:34 UTC (permalink / raw)
To: Ben Dooks
Cc: Michael Wu, David Miller, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Ivo van Doorn, Jeff Garzik
On Mon, May 07, 2007 at 02:27:15PM +0000, Ben Dooks wrote:
> On Mon, May 07, 2007 at 03:46:04AM -0400, Michael Wu wrote:
> > From: Ivo van Doorn <ivdoorn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> >
> > This patch adds a library for reading from and writing to 93cx6 eeproms.
>
> This looks remarkably like an SPI device, why not use the
> spi framework to drive this?
This isn't intended to be a user-visible device. Rather, it
is a support library for internal use by drivers to read hardware
configuration info, etc. Given that, do we really need something as
heavy as implementing an SPI master, etc?
John
--
John W. Linville
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] Add 93cx6 eeprom library
[not found] ` <20070507142715.GB32546-elnMNo+KYs3pIgCt6eIbzw@public.gmane.org>
2007-05-07 15:34 ` John W. Linville
@ 2007-05-07 15:40 ` Michael Wu
1 sibling, 0 replies; 5+ messages in thread
From: Michael Wu @ 2007-05-07 15:40 UTC (permalink / raw)
To: Ben Dooks
Cc: David Miller, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, John Linville, Ivo van Doorn,
Jeff Garzik
[-- Attachment #1: Type: text/plain, Size: 738 bytes --]
On Monday 07 May 2007 10:27, Ben Dooks wrote:
> On Mon, May 07, 2007 at 03:46:04AM -0400, Michael Wu wrote:
> > From: Ivo van Doorn <ivdoorn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> >
> > This patch adds a library for reading from and writing to 93cx6 eeproms.
>
> This looks remarkably like an SPI device, why not use the
> spi framework to drive this?
>
Yeah, it's SPI/microwire. As for using the SPI framework.. I dunno. The rt2x00
drivers depend on this too and I'd rather not change the code at this point
since it's well tested and working. Thanks for the heads up about using SPI,
however. I (or maybe Ivo if he has any time) will check the SPI framework
later and see if that simplifies things.
-Michael Wu
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-05-07 15:40 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-07 7:46 [PATCH 1/2] Add 93cx6 eeprom library Michael Wu
[not found] ` <200705070346.04982.flamingice-R9e9/4HEdknk1uMJSBkQmQ@public.gmane.org>
2007-05-07 7:53 ` Ivo van Doorn
2007-05-07 14:27 ` Ben Dooks
[not found] ` <20070507142715.GB32546-elnMNo+KYs3pIgCt6eIbzw@public.gmane.org>
2007-05-07 15:34 ` John W. Linville
2007-05-07 15:40 ` Michael Wu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).