1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * I2C slave mode EEPROM simulator
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2014 by Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
6*4882a593Smuzhiyun * Copyright (C) 2014 by Renesas Electronics Corporation
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Because most slave IP cores can only detect one I2C slave address anyhow,
9*4882a593Smuzhiyun * this driver does not support simulating EEPROM types which take more than
10*4882a593Smuzhiyun * one address.
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun /*
14*4882a593Smuzhiyun * FIXME: What to do if only 8 bits of a 16 bit address are sent?
15*4882a593Smuzhiyun * The ST-M24C64 sends only 0xff then. Needs verification with other
16*4882a593Smuzhiyun * EEPROMs, though. We currently use the 8 bit as a valid address.
17*4882a593Smuzhiyun */
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include <linux/bitfield.h>
20*4882a593Smuzhiyun #include <linux/firmware.h>
21*4882a593Smuzhiyun #include <linux/i2c.h>
22*4882a593Smuzhiyun #include <linux/init.h>
23*4882a593Smuzhiyun #include <linux/module.h>
24*4882a593Smuzhiyun #include <linux/of.h>
25*4882a593Smuzhiyun #include <linux/slab.h>
26*4882a593Smuzhiyun #include <linux/spinlock.h>
27*4882a593Smuzhiyun #include <linux/sysfs.h>
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun struct eeprom_data {
30*4882a593Smuzhiyun struct bin_attribute bin;
31*4882a593Smuzhiyun spinlock_t buffer_lock;
32*4882a593Smuzhiyun u16 buffer_idx;
33*4882a593Smuzhiyun u16 address_mask;
34*4882a593Smuzhiyun u8 num_address_bytes;
35*4882a593Smuzhiyun u8 idx_write_cnt;
36*4882a593Smuzhiyun bool read_only;
37*4882a593Smuzhiyun u8 buffer[];
38*4882a593Smuzhiyun };
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #define I2C_SLAVE_BYTELEN GENMASK(15, 0)
41*4882a593Smuzhiyun #define I2C_SLAVE_FLAG_ADDR16 BIT(16)
42*4882a593Smuzhiyun #define I2C_SLAVE_FLAG_RO BIT(17)
43*4882a593Smuzhiyun #define I2C_SLAVE_DEVICE_MAGIC(_len, _flags) ((_flags) | ((_len) - 1))
44*4882a593Smuzhiyun
i2c_slave_eeprom_slave_cb(struct i2c_client * client,enum i2c_slave_event event,u8 * val)45*4882a593Smuzhiyun static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
46*4882a593Smuzhiyun enum i2c_slave_event event, u8 *val)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun struct eeprom_data *eeprom = i2c_get_clientdata(client);
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun switch (event) {
51*4882a593Smuzhiyun case I2C_SLAVE_WRITE_RECEIVED:
52*4882a593Smuzhiyun if (eeprom->idx_write_cnt < eeprom->num_address_bytes) {
53*4882a593Smuzhiyun if (eeprom->idx_write_cnt == 0)
54*4882a593Smuzhiyun eeprom->buffer_idx = 0;
55*4882a593Smuzhiyun eeprom->buffer_idx = *val | (eeprom->buffer_idx << 8);
56*4882a593Smuzhiyun eeprom->idx_write_cnt++;
57*4882a593Smuzhiyun } else {
58*4882a593Smuzhiyun if (!eeprom->read_only) {
59*4882a593Smuzhiyun spin_lock(&eeprom->buffer_lock);
60*4882a593Smuzhiyun eeprom->buffer[eeprom->buffer_idx++ & eeprom->address_mask] = *val;
61*4882a593Smuzhiyun spin_unlock(&eeprom->buffer_lock);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun break;
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun case I2C_SLAVE_READ_PROCESSED:
67*4882a593Smuzhiyun /* The previous byte made it to the bus, get next one */
68*4882a593Smuzhiyun eeprom->buffer_idx++;
69*4882a593Smuzhiyun fallthrough;
70*4882a593Smuzhiyun case I2C_SLAVE_READ_REQUESTED:
71*4882a593Smuzhiyun spin_lock(&eeprom->buffer_lock);
72*4882a593Smuzhiyun *val = eeprom->buffer[eeprom->buffer_idx & eeprom->address_mask];
73*4882a593Smuzhiyun spin_unlock(&eeprom->buffer_lock);
74*4882a593Smuzhiyun /*
75*4882a593Smuzhiyun * Do not increment buffer_idx here, because we don't know if
76*4882a593Smuzhiyun * this byte will be actually used. Read Linux I2C slave docs
77*4882a593Smuzhiyun * for details.
78*4882a593Smuzhiyun */
79*4882a593Smuzhiyun break;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun case I2C_SLAVE_STOP:
82*4882a593Smuzhiyun case I2C_SLAVE_WRITE_REQUESTED:
83*4882a593Smuzhiyun eeprom->idx_write_cnt = 0;
84*4882a593Smuzhiyun break;
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun default:
87*4882a593Smuzhiyun break;
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun return 0;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun
i2c_slave_eeprom_bin_read(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t off,size_t count)93*4882a593Smuzhiyun static ssize_t i2c_slave_eeprom_bin_read(struct file *filp, struct kobject *kobj,
94*4882a593Smuzhiyun struct bin_attribute *attr, char *buf, loff_t off, size_t count)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun struct eeprom_data *eeprom;
97*4882a593Smuzhiyun unsigned long flags;
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun eeprom = dev_get_drvdata(kobj_to_dev(kobj));
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun spin_lock_irqsave(&eeprom->buffer_lock, flags);
102*4882a593Smuzhiyun memcpy(buf, &eeprom->buffer[off], count);
103*4882a593Smuzhiyun spin_unlock_irqrestore(&eeprom->buffer_lock, flags);
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun return count;
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
i2c_slave_eeprom_bin_write(struct file * filp,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t off,size_t count)108*4882a593Smuzhiyun static ssize_t i2c_slave_eeprom_bin_write(struct file *filp, struct kobject *kobj,
109*4882a593Smuzhiyun struct bin_attribute *attr, char *buf, loff_t off, size_t count)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun struct eeprom_data *eeprom;
112*4882a593Smuzhiyun unsigned long flags;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun eeprom = dev_get_drvdata(kobj_to_dev(kobj));
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun spin_lock_irqsave(&eeprom->buffer_lock, flags);
117*4882a593Smuzhiyun memcpy(&eeprom->buffer[off], buf, count);
118*4882a593Smuzhiyun spin_unlock_irqrestore(&eeprom->buffer_lock, flags);
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun return count;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun
i2c_slave_init_eeprom_data(struct eeprom_data * eeprom,struct i2c_client * client,unsigned int size)123*4882a593Smuzhiyun static int i2c_slave_init_eeprom_data(struct eeprom_data *eeprom, struct i2c_client *client,
124*4882a593Smuzhiyun unsigned int size)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun const struct firmware *fw;
127*4882a593Smuzhiyun const char *eeprom_data;
128*4882a593Smuzhiyun int ret = device_property_read_string(&client->dev, "firmware-name", &eeprom_data);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun if (!ret) {
131*4882a593Smuzhiyun ret = request_firmware_into_buf(&fw, eeprom_data, &client->dev,
132*4882a593Smuzhiyun eeprom->buffer, size);
133*4882a593Smuzhiyun if (ret)
134*4882a593Smuzhiyun return ret;
135*4882a593Smuzhiyun release_firmware(fw);
136*4882a593Smuzhiyun } else {
137*4882a593Smuzhiyun /* An empty eeprom typically has all bits set to 1 */
138*4882a593Smuzhiyun memset(eeprom->buffer, 0xff, size);
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun return 0;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
i2c_slave_eeprom_probe(struct i2c_client * client,const struct i2c_device_id * id)143*4882a593Smuzhiyun static int i2c_slave_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *id)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun struct eeprom_data *eeprom;
146*4882a593Smuzhiyun int ret;
147*4882a593Smuzhiyun unsigned int size = FIELD_GET(I2C_SLAVE_BYTELEN, id->driver_data) + 1;
148*4882a593Smuzhiyun unsigned int flag_addr16 = FIELD_GET(I2C_SLAVE_FLAG_ADDR16, id->driver_data);
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun eeprom = devm_kzalloc(&client->dev, sizeof(struct eeprom_data) + size, GFP_KERNEL);
151*4882a593Smuzhiyun if (!eeprom)
152*4882a593Smuzhiyun return -ENOMEM;
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun eeprom->num_address_bytes = flag_addr16 ? 2 : 1;
155*4882a593Smuzhiyun eeprom->address_mask = size - 1;
156*4882a593Smuzhiyun eeprom->read_only = FIELD_GET(I2C_SLAVE_FLAG_RO, id->driver_data);
157*4882a593Smuzhiyun spin_lock_init(&eeprom->buffer_lock);
158*4882a593Smuzhiyun i2c_set_clientdata(client, eeprom);
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun ret = i2c_slave_init_eeprom_data(eeprom, client, size);
161*4882a593Smuzhiyun if (ret)
162*4882a593Smuzhiyun return ret;
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun sysfs_bin_attr_init(&eeprom->bin);
165*4882a593Smuzhiyun eeprom->bin.attr.name = "slave-eeprom";
166*4882a593Smuzhiyun eeprom->bin.attr.mode = S_IRUSR | S_IWUSR;
167*4882a593Smuzhiyun eeprom->bin.read = i2c_slave_eeprom_bin_read;
168*4882a593Smuzhiyun eeprom->bin.write = i2c_slave_eeprom_bin_write;
169*4882a593Smuzhiyun eeprom->bin.size = size;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun ret = sysfs_create_bin_file(&client->dev.kobj, &eeprom->bin);
172*4882a593Smuzhiyun if (ret)
173*4882a593Smuzhiyun return ret;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun ret = i2c_slave_register(client, i2c_slave_eeprom_slave_cb);
176*4882a593Smuzhiyun if (ret) {
177*4882a593Smuzhiyun sysfs_remove_bin_file(&client->dev.kobj, &eeprom->bin);
178*4882a593Smuzhiyun return ret;
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun return 0;
182*4882a593Smuzhiyun };
183*4882a593Smuzhiyun
i2c_slave_eeprom_remove(struct i2c_client * client)184*4882a593Smuzhiyun static int i2c_slave_eeprom_remove(struct i2c_client *client)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun struct eeprom_data *eeprom = i2c_get_clientdata(client);
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun i2c_slave_unregister(client);
189*4882a593Smuzhiyun sysfs_remove_bin_file(&client->dev.kobj, &eeprom->bin);
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun return 0;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun static const struct i2c_device_id i2c_slave_eeprom_id[] = {
195*4882a593Smuzhiyun { "slave-24c02", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, 0) },
196*4882a593Smuzhiyun { "slave-24c02ro", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, I2C_SLAVE_FLAG_RO) },
197*4882a593Smuzhiyun { "slave-24c32", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16) },
198*4882a593Smuzhiyun { "slave-24c32ro", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
199*4882a593Smuzhiyun { "slave-24c64", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16) },
200*4882a593Smuzhiyun { "slave-24c64ro", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
201*4882a593Smuzhiyun { "slave-24c512", I2C_SLAVE_DEVICE_MAGIC(524288 / 8, I2C_SLAVE_FLAG_ADDR16) },
202*4882a593Smuzhiyun { "slave-24c512ro", I2C_SLAVE_DEVICE_MAGIC(524288 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
203*4882a593Smuzhiyun { }
204*4882a593Smuzhiyun };
205*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, i2c_slave_eeprom_id);
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun static struct i2c_driver i2c_slave_eeprom_driver = {
208*4882a593Smuzhiyun .driver = {
209*4882a593Smuzhiyun .name = "i2c-slave-eeprom",
210*4882a593Smuzhiyun },
211*4882a593Smuzhiyun .probe = i2c_slave_eeprom_probe,
212*4882a593Smuzhiyun .remove = i2c_slave_eeprom_remove,
213*4882a593Smuzhiyun .id_table = i2c_slave_eeprom_id,
214*4882a593Smuzhiyun };
215*4882a593Smuzhiyun module_i2c_driver(i2c_slave_eeprom_driver);
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");
218*4882a593Smuzhiyun MODULE_DESCRIPTION("I2C slave mode EEPROM simulator");
219*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
220