aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic-2.6
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic-2.6')
-rw-r--r--target/linux/generic-2.6/patches-2.6.27/450-i2c_at24_add_kernel_interface_read_write.patch134
1 files changed, 134 insertions, 0 deletions
diff --git a/target/linux/generic-2.6/patches-2.6.27/450-i2c_at24_add_kernel_interface_read_write.patch b/target/linux/generic-2.6/patches-2.6.27/450-i2c_at24_add_kernel_interface_read_write.patch
new file mode 100644
index 0000000000..36a3e69125
--- /dev/null
+++ b/target/linux/generic-2.6/patches-2.6.27/450-i2c_at24_add_kernel_interface_read_write.patch
@@ -0,0 +1,134 @@
+Subject: [PATCH 2/3] I2C: at24: add kernel interface for reading/writing EEPROM
+Date: Monday 25 August 2008
+From: Kevin Hilman <khilman@deeprootsystems.com>
+To: davinci-linux-open-source@linux.davincidsp.com
+
+This patch adds an interface by which other kernel code can read/write
+detected EEPROM.
+
+The platform code registers a 'setup' callback with the
+at24_platform_data. When the at24 driver detects an EEPROM, it fills
+out the read and write functions of at24_iface and calls the setup
+callback. The platform code can then use the read/write functions in
+the at24_iface struct for reading and writing the EEPROM.
+
+Original idea, review and updates by David Brownell <david-b@pacbell.net>
+
+Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
+---
+ drivers/i2c/chips/at24.c | 42 +++++++++++++++++++++++++++++++++++-------
+ include/linux/i2c/at24.h | 10 ++++++++++
+ 2 files changed, 45 insertions(+), 7 deletions(-)
+
+--- a/drivers/i2c/chips/at24.c
++++ b/drivers/i2c/chips/at24.c
+@@ -53,6 +53,7 @@
+
+ struct at24_data {
+ struct at24_platform_data chip;
++ struct at24_iface iface;
+ bool use_smbus;
+
+ /*
+@@ -264,13 +265,6 @@ static ssize_t at24_bin_read(struct kobj
+
+
+ /*
+- * REVISIT: export at24_bin{read,write}() to let other kernel code use
+- * eeprom data. For example, it might hold a board's Ethernet address, or
+- * board-specific calibration data generated on the manufacturing floor.
+- */
+-
+-
+-/*
+ * Note that if the hardware write-protect pin is pulled high, the whole
+ * chip is normally write protected. But there are plenty of product
+ * variants here, including OTP fuses and partial chip protect.
+@@ -386,6 +380,30 @@ static ssize_t at24_bin_write(struct kob
+
+ /*-------------------------------------------------------------------------*/
+
++/*
++ * This lets other kernel code access the eeprom data. For example, it
++ * might hold a board's Ethernet address, or board-specific calibration
++ * data generated on the manufacturing floor.
++ */
++
++static ssize_t at24_iface_read(struct at24_iface *iface, char *buf,
++ off_t offset, size_t count)
++{
++ struct at24_data *at24 = container_of(iface, struct at24_data, iface);
++
++ return at24_eeprom_read(at24, buf, offset, count);
++}
++
++static ssize_t at24_iface_write(struct at24_iface *iface, char *buf,
++ off_t offset, size_t count)
++{
++ struct at24_data *at24 = container_of(iface, struct at24_data, iface);
++
++ return at24_eeprom_write(at24, buf, offset, count);
++}
++
++/*-------------------------------------------------------------------------*/
++
+ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
+ {
+ struct at24_platform_data chip;
+@@ -413,6 +431,9 @@ static int at24_probe(struct i2c_client
+ * is recommended anyhow.
+ */
+ chip.page_size = 1;
++
++ chip.setup = NULL;
++ chip.context = NULL;
+ }
+
+ if (!is_power_of_2(chip.byte_len))
+@@ -449,6 +470,9 @@ static int at24_probe(struct i2c_client
+ goto err_out;
+ }
+
++ at24->iface.read = at24_iface_read;
++ at24->iface.write = at24_iface_write;
++
+ mutex_init(&at24->lock);
+ at24->use_smbus = use_smbus;
+ at24->chip = chip;
+@@ -521,6 +545,10 @@ static int at24_probe(struct i2c_client
+ at24->write_max,
+ use_smbus ? ", use_smbus" : "");
+
++ /* export data to kernel code */
++ if (chip.setup)
++ chip.setup(&at24->iface, chip.context);
++
+ return 0;
+
+ err_clients:
+--- a/include/linux/i2c/at24.h
++++ b/include/linux/i2c/at24.h
+@@ -15,6 +15,13 @@
+ * is bigger than what the chip actually supports!
+ */
+
++struct at24_iface {
++ ssize_t (*read)(struct at24_iface *, char *buf, off_t offset,
++ size_t count);
++ ssize_t (*write)(struct at24_iface *, char *buf, off_t offset,
++ size_t count);
++};
++
+ struct at24_platform_data {
+ u32 byte_len; /* size (sum of all addr) */
+ u16 page_size; /* for writes */
+@@ -23,6 +30,9 @@ struct at24_platform_data {
+ #define AT24_FLAG_READONLY 0x40 /* sysfs-entry will be read-only */
+ #define AT24_FLAG_IRUGO 0x20 /* sysfs-entry will be world-readable */
+ #define AT24_FLAG_TAKE8ADDR 0x10 /* take always 8 addresses (24c00) */
++
++ int (*setup)(struct at24_iface *, void *context);
++ void *context;
+ };
+
+ #endif /* _LINUX_AT24_H */