Merge tag 'exfat-for-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linki...
[linux-2.6-microblaze.git] / drivers / misc / eeprom / max6875.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * max6875.c - driver for MAX6874/MAX6875
4  *
5  * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
6  *
7  * Based on eeprom.c
8  *
9  * The MAX6875 has a bank of registers and two banks of EEPROM.
10  * Address ranges are defined as follows:
11  *  * 0x0000 - 0x0046 = configuration registers
12  *  * 0x8000 - 0x8046 = configuration EEPROM
13  *  * 0x8100 - 0x82FF = user EEPROM
14  *
15  * This driver makes the user EEPROM available for read.
16  *
17  * The registers & config EEPROM should be accessed via i2c-dev.
18  *
19  * The MAX6875 ignores the lowest address bit, so each chip responds to
20  * two addresses - 0x50/0x51 and 0x52/0x53.
21  *
22  * Note that the MAX6875 uses i2c_smbus_write_byte_data() to set the read
23  * address, so this driver is destructive if loaded for the wrong EEPROM chip.
24  */
25
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/slab.h>
29 #include <linux/i2c.h>
30 #include <linux/mutex.h>
31
32 /* The MAX6875 can only read/write 16 bytes at a time */
33 #define SLICE_SIZE                      16
34 #define SLICE_BITS                      4
35
36 /* USER EEPROM is at addresses 0x8100 - 0x82FF */
37 #define USER_EEPROM_BASE                0x8100
38 #define USER_EEPROM_SIZE                0x0200
39 #define USER_EEPROM_SLICES              32
40
41 /* MAX6875 commands */
42 #define MAX6875_CMD_BLK_READ            0x84
43
44 /* Each client has this additional data */
45 struct max6875_data {
46         struct i2c_client       *fake_client;
47         struct mutex            update_lock;
48
49         u32                     valid;
50         u8                      data[USER_EEPROM_SIZE];
51         unsigned long           last_updated[USER_EEPROM_SLICES];
52 };
53
54 static void max6875_update_slice(struct i2c_client *client, int slice)
55 {
56         struct max6875_data *data = i2c_get_clientdata(client);
57         int i, j, addr;
58         u8 *buf;
59
60         if (slice >= USER_EEPROM_SLICES)
61                 return;
62
63         mutex_lock(&data->update_lock);
64
65         buf = &data->data[slice << SLICE_BITS];
66
67         if (!(data->valid & (1 << slice)) ||
68             time_after(jiffies, data->last_updated[slice])) {
69
70                 dev_dbg(&client->dev, "Starting update of slice %u\n", slice);
71
72                 data->valid &= ~(1 << slice);
73
74                 addr = USER_EEPROM_BASE + (slice << SLICE_BITS);
75
76                 /* select the eeprom address */
77                 if (i2c_smbus_write_byte_data(client, addr >> 8, addr & 0xFF)) {
78                         dev_err(&client->dev, "address set failed\n");
79                         goto exit_up;
80                 }
81
82                 if (i2c_check_functionality(client->adapter,
83                                             I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
84                         if (i2c_smbus_read_i2c_block_data(client,
85                                                           MAX6875_CMD_BLK_READ,
86                                                           SLICE_SIZE,
87                                                           buf) != SLICE_SIZE) {
88                                 goto exit_up;
89                         }
90                 } else {
91                         for (i = 0; i < SLICE_SIZE; i++) {
92                                 j = i2c_smbus_read_byte(client);
93                                 if (j < 0) {
94                                         goto exit_up;
95                                 }
96                                 buf[i] = j;
97                         }
98                 }
99                 data->last_updated[slice] = jiffies;
100                 data->valid |= (1 << slice);
101         }
102 exit_up:
103         mutex_unlock(&data->update_lock);
104 }
105
106 static ssize_t max6875_read(struct file *filp, struct kobject *kobj,
107                             struct bin_attribute *bin_attr,
108                             char *buf, loff_t off, size_t count)
109 {
110         struct i2c_client *client = kobj_to_i2c_client(kobj);
111         struct max6875_data *data = i2c_get_clientdata(client);
112         int slice, max_slice;
113
114         /* refresh slices which contain requested bytes */
115         max_slice = (off + count - 1) >> SLICE_BITS;
116         for (slice = (off >> SLICE_BITS); slice <= max_slice; slice++)
117                 max6875_update_slice(client, slice);
118
119         memcpy(buf, &data->data[off], count);
120
121         return count;
122 }
123
124 static const struct bin_attribute user_eeprom_attr = {
125         .attr = {
126                 .name = "eeprom",
127                 .mode = S_IRUGO,
128         },
129         .size = USER_EEPROM_SIZE,
130         .read = max6875_read,
131 };
132
133 static int max6875_probe(struct i2c_client *client,
134                          const struct i2c_device_id *id)
135 {
136         struct i2c_adapter *adapter = client->adapter;
137         struct max6875_data *data;
138         int err;
139
140         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
141                                      | I2C_FUNC_SMBUS_READ_BYTE))
142                 return -ENODEV;
143
144         /* Only bind to even addresses */
145         if (client->addr & 1)
146                 return -ENODEV;
147
148         data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL);
149         if (!data)
150                 return -ENOMEM;
151
152         /* A fake client is created on the odd address */
153         data->fake_client = i2c_new_dummy_device(client->adapter, client->addr + 1);
154         if (IS_ERR(data->fake_client)) {
155                 err = PTR_ERR(data->fake_client);
156                 goto exit_kfree;
157         }
158
159         /* Init real i2c_client */
160         i2c_set_clientdata(client, data);
161         mutex_init(&data->update_lock);
162
163         err = sysfs_create_bin_file(&client->dev.kobj, &user_eeprom_attr);
164         if (err)
165                 goto exit_remove_fake;
166
167         return 0;
168
169 exit_remove_fake:
170         i2c_unregister_device(data->fake_client);
171 exit_kfree:
172         kfree(data);
173         return err;
174 }
175
176 static int max6875_remove(struct i2c_client *client)
177 {
178         struct max6875_data *data = i2c_get_clientdata(client);
179
180         i2c_unregister_device(data->fake_client);
181
182         sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
183         kfree(data);
184
185         return 0;
186 }
187
188 static const struct i2c_device_id max6875_id[] = {
189         { "max6875", 0 },
190         { }
191 };
192 MODULE_DEVICE_TABLE(i2c, max6875_id);
193
194 static struct i2c_driver max6875_driver = {
195         .driver = {
196                 .name   = "max6875",
197         },
198         .probe          = max6875_probe,
199         .remove         = max6875_remove,
200         .id_table       = max6875_id,
201 };
202
203 module_i2c_driver(max6875_driver);
204
205 MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
206 MODULE_DESCRIPTION("MAX6875 driver");
207 MODULE_LICENSE("GPL");