1 Subject: [PATCH 2/3] I2C: at24: add kernel interface for reading/writing EEPROM
2 Date: Monday 25 August 2008
3 From: Kevin Hilman <khilman@deeprootsystems.com>
4 To: davinci-linux-open-source@linux.davincidsp.com
6 This patch adds an interface by which other kernel code can read/write
9 The platform code registers a 'setup' callback with the
10 at24_platform_data. When the at24 driver detects an EEPROM, it fills
11 out the read and write functions of at24_iface and calls the setup
12 callback. The platform code can then use the read/write functions in
13 the at24_iface struct for reading and writing the EEPROM.
15 Original idea, review and updates by David Brownell <david-b@pacbell.net>
17 Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
19 drivers/i2c/chips/at24.c | 42 +++++++++++++++++++++++++++++++++++-------
20 include/linux/i2c/at24.h | 10 ++++++++++
21 2 files changed, 45 insertions(+), 7 deletions(-)
23 --- a/drivers/i2c/chips/at24.c
24 +++ b/drivers/i2c/chips/at24.c
28 struct at24_platform_data chip;
29 + struct at24_iface iface;
33 @@ -264,13 +265,6 @@ static ssize_t at24_bin_read(struct kobj
37 - * REVISIT: export at24_bin{read,write}() to let other kernel code use
38 - * eeprom data. For example, it might hold a board's Ethernet address, or
39 - * board-specific calibration data generated on the manufacturing floor.
44 * Note that if the hardware write-protect pin is pulled high, the whole
45 * chip is normally write protected. But there are plenty of product
46 * variants here, including OTP fuses and partial chip protect.
47 @@ -386,6 +380,30 @@ static ssize_t at24_bin_write(struct kob
49 /*-------------------------------------------------------------------------*/
52 + * This lets other kernel code access the eeprom data. For example, it
53 + * might hold a board's Ethernet address, or board-specific calibration
54 + * data generated on the manufacturing floor.
57 +static ssize_t at24_iface_read(struct at24_iface *iface, char *buf,
58 + off_t offset, size_t count)
60 + struct at24_data *at24 = container_of(iface, struct at24_data, iface);
62 + return at24_eeprom_read(at24, buf, offset, count);
65 +static ssize_t at24_iface_write(struct at24_iface *iface, char *buf,
66 + off_t offset, size_t count)
68 + struct at24_data *at24 = container_of(iface, struct at24_data, iface);
70 + return at24_eeprom_write(at24, buf, offset, count);
73 +/*-------------------------------------------------------------------------*/
75 static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
77 struct at24_platform_data chip;
78 @@ -413,6 +431,9 @@ static int at24_probe(struct i2c_client
79 * is recommended anyhow.
84 + chip.context = NULL;
87 if (!is_power_of_2(chip.byte_len))
88 @@ -449,6 +470,9 @@ static int at24_probe(struct i2c_client
92 + at24->iface.read = at24_iface_read;
93 + at24->iface.write = at24_iface_write;
95 mutex_init(&at24->lock);
96 at24->use_smbus = use_smbus;
98 @@ -520,6 +544,10 @@ static int at24_probe(struct i2c_client
100 use_smbus ? ", use_smbus" : "");
102 + /* export data to kernel code */
104 + chip.setup(&at24->iface, chip.context);
109 --- a/include/linux/i2c/at24.h
110 +++ b/include/linux/i2c/at24.h
112 * is bigger than what the chip actually supports!
116 + ssize_t (*read)(struct at24_iface *, char *buf, off_t offset,
118 + ssize_t (*write)(struct at24_iface *, char *buf, off_t offset,
122 struct at24_platform_data {
123 u32 byte_len; /* size (sum of all addr) */
124 u16 page_size; /* for writes */
125 @@ -23,6 +30,9 @@ struct at24_platform_data {
126 #define AT24_FLAG_READONLY 0x40 /* sysfs-entry will be read-only */
127 #define AT24_FLAG_IRUGO 0x20 /* sysfs-entry will be world-readable */
128 #define AT24_FLAG_TAKE8ADDR 0x10 /* take always 8 addresses (24c00) */
130 + int (*setup)(struct at24_iface *, void *context);
134 #endif /* _LINUX_AT24_H */