[kernel] revert 15922 - add back 2.6.29 kernel support
[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 */