revert 15922 - add back 2.6.29 kernel support
[openwrt/openwrt.git] / target / linux / generic-2.6 / patches-2.6.29 / 450-i2c_at24_add_kernel_interface_read_write.patch
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
5
6 This patch adds an interface by which other kernel code can read/write
7 detected EEPROM.
8
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.
14
15 Original idea, review and updates by David Brownell <david-b@pacbell.net>
16
17 Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
18 ---
19 drivers/i2c/chips/at24.c | 42 +++++++++++++++++++++++++++++++++++-------
20 include/linux/i2c/at24.h | 10 ++++++++++
21 2 files changed, 45 insertions(+), 7 deletions(-)
22
23 --- a/drivers/misc/eeprom/at24.c
24 +++ b/drivers/misc/eeprom/at24.c
25 @@ -53,6 +53,7 @@
26
27 struct at24_data {
28 struct at24_platform_data chip;
29 + struct at24_iface iface;
30 bool use_smbus;
31
32 /*
33 @@ -264,13 +265,6 @@ static ssize_t at24_bin_read(struct kobj
34
35
36 /*
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.
40 - */
41 -
42 -
43 -/*
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
48
49 /*-------------------------------------------------------------------------*/
50
51 +/*
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.
55 + */
56 +
57 +static ssize_t at24_iface_read(struct at24_iface *iface, char *buf,
58 + off_t offset, size_t count)
59 +{
60 + struct at24_data *at24 = container_of(iface, struct at24_data, iface);
61 +
62 + return at24_eeprom_read(at24, buf, offset, count);
63 +}
64 +
65 +static ssize_t at24_iface_write(struct at24_iface *iface, char *buf,
66 + off_t offset, size_t count)
67 +{
68 + struct at24_data *at24 = container_of(iface, struct at24_data, iface);
69 +
70 + return at24_eeprom_write(at24, buf, offset, count);
71 +}
72 +
73 +/*-------------------------------------------------------------------------*/
74 +
75 static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
76 {
77 struct at24_platform_data chip;
78 @@ -413,6 +431,9 @@ static int at24_probe(struct i2c_client
79 * is recommended anyhow.
80 */
81 chip.page_size = 1;
82 +
83 + chip.setup = NULL;
84 + chip.context = NULL;
85 }
86
87 if (!is_power_of_2(chip.byte_len))
88 @@ -449,6 +470,9 @@ static int at24_probe(struct i2c_client
89 goto err_out;
90 }
91
92 + at24->iface.read = at24_iface_read;
93 + at24->iface.write = at24_iface_write;
94 +
95 mutex_init(&at24->lock);
96 at24->use_smbus = use_smbus;
97 at24->chip = chip;
98 @@ -520,6 +544,10 @@ static int at24_probe(struct i2c_client
99 at24->write_max,
100 use_smbus ? ", use_smbus" : "");
101
102 + /* export data to kernel code */
103 + if (chip.setup)
104 + chip.setup(&at24->iface, chip.context);
105 +
106 return 0;
107
108 err_clients:
109 --- a/include/linux/i2c/at24.h
110 +++ b/include/linux/i2c/at24.h
111 @@ -15,6 +15,13 @@
112 * is bigger than what the chip actually supports!
113 */
114
115 +struct at24_iface {
116 + ssize_t (*read)(struct at24_iface *, char *buf, off_t offset,
117 + size_t count);
118 + ssize_t (*write)(struct at24_iface *, char *buf, off_t offset,
119 + size_t count);
120 +};
121 +
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) */
129 +
130 + int (*setup)(struct at24_iface *, void *context);
131 + void *context;
132 };
133
134 #endif /* _LINUX_AT24_H */