hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/i2c/i2c-slave-eeprom.c
....@@ -1,19 +1,23 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * I2C slave mode EEPROM simulator
34 *
45 * Copyright (C) 2014 by Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
56 * Copyright (C) 2014 by Renesas Electronics Corporation
67 *
7
- * This program is free software; you can redistribute it and/or modify it
8
- * under the terms of the GNU General Public License as published by the
9
- * Free Software Foundation; version 2 of the License.
10
- *
11
- * Because most IP blocks can only detect one I2C slave address anyhow, this
12
- * driver does not support simulating EEPROM types which take more than one
13
- * address. It is prepared to simulate bigger EEPROMs with an internal 16 bit
14
- * pointer, yet implementation is deferred until the need actually arises.
8
+ * Because most slave IP cores can only detect one I2C slave address anyhow,
9
+ * this driver does not support simulating EEPROM types which take more than
10
+ * one address.
1511 */
1612
13
+/*
14
+ * FIXME: What to do if only 8 bits of a 16 bit address are sent?
15
+ * The ST-M24C64 sends only 0xff then. Needs verification with other
16
+ * EEPROMs, though. We currently use the 8 bit as a valid address.
17
+ */
18
+
19
+#include <linux/bitfield.h>
20
+#include <linux/firmware.h>
1721 #include <linux/i2c.h>
1822 #include <linux/init.h>
1923 #include <linux/module.h>
....@@ -24,11 +28,19 @@
2428
2529 struct eeprom_data {
2630 struct bin_attribute bin;
27
- bool first_write;
2831 spinlock_t buffer_lock;
29
- u8 buffer_idx;
32
+ u16 buffer_idx;
33
+ u16 address_mask;
34
+ u8 num_address_bytes;
35
+ u8 idx_write_cnt;
36
+ bool read_only;
3037 u8 buffer[];
3138 };
39
+
40
+#define I2C_SLAVE_BYTELEN GENMASK(15, 0)
41
+#define I2C_SLAVE_FLAG_ADDR16 BIT(16)
42
+#define I2C_SLAVE_FLAG_RO BIT(17)
43
+#define I2C_SLAVE_DEVICE_MAGIC(_len, _flags) ((_flags) | ((_len) - 1))
3244
3345 static int i2c_slave_eeprom_slave_cb(struct i2c_client *client,
3446 enum i2c_slave_event event, u8 *val)
....@@ -37,23 +49,27 @@
3749
3850 switch (event) {
3951 case I2C_SLAVE_WRITE_RECEIVED:
40
- if (eeprom->first_write) {
41
- eeprom->buffer_idx = *val;
42
- eeprom->first_write = false;
52
+ if (eeprom->idx_write_cnt < eeprom->num_address_bytes) {
53
+ if (eeprom->idx_write_cnt == 0)
54
+ eeprom->buffer_idx = 0;
55
+ eeprom->buffer_idx = *val | (eeprom->buffer_idx << 8);
56
+ eeprom->idx_write_cnt++;
4357 } else {
44
- spin_lock(&eeprom->buffer_lock);
45
- eeprom->buffer[eeprom->buffer_idx++] = *val;
46
- spin_unlock(&eeprom->buffer_lock);
58
+ if (!eeprom->read_only) {
59
+ spin_lock(&eeprom->buffer_lock);
60
+ eeprom->buffer[eeprom->buffer_idx++ & eeprom->address_mask] = *val;
61
+ spin_unlock(&eeprom->buffer_lock);
62
+ }
4763 }
4864 break;
4965
5066 case I2C_SLAVE_READ_PROCESSED:
5167 /* The previous byte made it to the bus, get next one */
5268 eeprom->buffer_idx++;
53
- /* fallthrough */
69
+ fallthrough;
5470 case I2C_SLAVE_READ_REQUESTED:
5571 spin_lock(&eeprom->buffer_lock);
56
- *val = eeprom->buffer[eeprom->buffer_idx];
72
+ *val = eeprom->buffer[eeprom->buffer_idx & eeprom->address_mask];
5773 spin_unlock(&eeprom->buffer_lock);
5874 /*
5975 * Do not increment buffer_idx here, because we don't know if
....@@ -64,7 +80,7 @@
6480
6581 case I2C_SLAVE_STOP:
6682 case I2C_SLAVE_WRITE_REQUESTED:
67
- eeprom->first_write = true;
83
+ eeprom->idx_write_cnt = 0;
6884 break;
6985
7086 default:
....@@ -80,7 +96,7 @@
8096 struct eeprom_data *eeprom;
8197 unsigned long flags;
8298
83
- eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj));
99
+ eeprom = dev_get_drvdata(kobj_to_dev(kobj));
84100
85101 spin_lock_irqsave(&eeprom->buffer_lock, flags);
86102 memcpy(buf, &eeprom->buffer[off], count);
....@@ -95,7 +111,7 @@
95111 struct eeprom_data *eeprom;
96112 unsigned long flags;
97113
98
- eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj));
114
+ eeprom = dev_get_drvdata(kobj_to_dev(kobj));
99115
100116 spin_lock_irqsave(&eeprom->buffer_lock, flags);
101117 memcpy(&eeprom->buffer[off], buf, count);
....@@ -104,19 +120,46 @@
104120 return count;
105121 }
106122
123
+static int i2c_slave_init_eeprom_data(struct eeprom_data *eeprom, struct i2c_client *client,
124
+ unsigned int size)
125
+{
126
+ const struct firmware *fw;
127
+ const char *eeprom_data;
128
+ int ret = device_property_read_string(&client->dev, "firmware-name", &eeprom_data);
129
+
130
+ if (!ret) {
131
+ ret = request_firmware_into_buf(&fw, eeprom_data, &client->dev,
132
+ eeprom->buffer, size);
133
+ if (ret)
134
+ return ret;
135
+ release_firmware(fw);
136
+ } else {
137
+ /* An empty eeprom typically has all bits set to 1 */
138
+ memset(eeprom->buffer, 0xff, size);
139
+ }
140
+ return 0;
141
+}
142
+
107143 static int i2c_slave_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *id)
108144 {
109145 struct eeprom_data *eeprom;
110146 int ret;
111
- unsigned size = id->driver_data;
147
+ unsigned int size = FIELD_GET(I2C_SLAVE_BYTELEN, id->driver_data) + 1;
148
+ unsigned int flag_addr16 = FIELD_GET(I2C_SLAVE_FLAG_ADDR16, id->driver_data);
112149
113150 eeprom = devm_kzalloc(&client->dev, sizeof(struct eeprom_data) + size, GFP_KERNEL);
114151 if (!eeprom)
115152 return -ENOMEM;
116153
117
- eeprom->first_write = true;
154
+ eeprom->num_address_bytes = flag_addr16 ? 2 : 1;
155
+ eeprom->address_mask = size - 1;
156
+ eeprom->read_only = FIELD_GET(I2C_SLAVE_FLAG_RO, id->driver_data);
118157 spin_lock_init(&eeprom->buffer_lock);
119158 i2c_set_clientdata(client, eeprom);
159
+
160
+ ret = i2c_slave_init_eeprom_data(eeprom, client, size);
161
+ if (ret)
162
+ return ret;
120163
121164 sysfs_bin_attr_init(&eeprom->bin);
122165 eeprom->bin.attr.name = "slave-eeprom";
....@@ -149,7 +192,14 @@
149192 }
150193
151194 static const struct i2c_device_id i2c_slave_eeprom_id[] = {
152
- { "slave-24c02", 2048 / 8 },
195
+ { "slave-24c02", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, 0) },
196
+ { "slave-24c02ro", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, I2C_SLAVE_FLAG_RO) },
197
+ { "slave-24c32", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16) },
198
+ { "slave-24c32ro", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
199
+ { "slave-24c64", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16) },
200
+ { "slave-24c64ro", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
201
+ { "slave-24c512", I2C_SLAVE_DEVICE_MAGIC(524288 / 8, I2C_SLAVE_FLAG_ADDR16) },
202
+ { "slave-24c512ro", I2C_SLAVE_DEVICE_MAGIC(524288 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
153203 { }
154204 };
155205 MODULE_DEVICE_TABLE(i2c, i2c_slave_eeprom_id);