1b886d83cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2389be323SWolfram Sang /* 3389be323SWolfram Sang * I2C slave mode EEPROM simulator 4389be323SWolfram Sang * 5389be323SWolfram Sang * Copyright (C) 2014 by Wolfram Sang, Sang Engineering <wsa@sang-engineering.com> 6389be323SWolfram Sang * Copyright (C) 2014 by Renesas Electronics Corporation 7389be323SWolfram Sang * 8468ed57fSWolfram Sang * Because most slave IP cores can only detect one I2C slave address anyhow, 9468ed57fSWolfram Sang * this driver does not support simulating EEPROM types which take more than 10468ed57fSWolfram Sang * one address. 11389be323SWolfram Sang */ 12389be323SWolfram Sang 13fe050f99SBjörn Ardö /* 14fe050f99SBjörn Ardö * FIXME: What to do if only 8 bits of a 16 bit address are sent? 15fe050f99SBjörn Ardö * The ST-M24C64 sends only 0xff then. Needs verification with other 16fe050f99SBjörn Ardö * EEPROMs, though. We currently use the 8 bit as a valid address. 17fe050f99SBjörn Ardö */ 18fe050f99SBjörn Ardö 1982d51481SBjörn Ardö #include <linux/bitfield.h> 20e804f0a7SBjörn Ardö #include <linux/firmware.h> 21389be323SWolfram Sang #include <linux/i2c.h> 22389be323SWolfram Sang #include <linux/init.h> 23389be323SWolfram Sang #include <linux/module.h> 24389be323SWolfram Sang #include <linux/of.h> 25389be323SWolfram Sang #include <linux/slab.h> 26389be323SWolfram Sang #include <linux/spinlock.h> 27389be323SWolfram Sang #include <linux/sysfs.h> 28389be323SWolfram Sang 29389be323SWolfram Sang struct eeprom_data { 30389be323SWolfram Sang struct bin_attribute bin; 31389be323SWolfram Sang spinlock_t buffer_lock; 3282d51481SBjörn Ardö u16 buffer_idx; 3382d51481SBjörn Ardö u16 address_mask; 3482d51481SBjörn Ardö u8 num_address_bytes; 3582d51481SBjörn Ardö u8 idx_write_cnt; 3611af27f4SBjörn Ardö bool read_only; 37389be323SWolfram Sang u8 buffer[]; 38389be323SWolfram Sang }; 39389be323SWolfram Sang 4082d51481SBjörn Ardö #define I2C_SLAVE_BYTELEN GENMASK(15, 0) 4182d51481SBjörn Ardö #define I2C_SLAVE_FLAG_ADDR16 BIT(16) 4211af27f4SBjörn Ardö #define I2C_SLAVE_FLAG_RO BIT(17) 435c71ca4dSWolfram Sang #define I2C_SLAVE_DEVICE_MAGIC(_len, _flags) ((_flags) | ((_len) - 1)) 4482d51481SBjörn Ardö 45389be323SWolfram Sang static int i2c_slave_eeprom_slave_cb(struct i2c_client *client, 46389be323SWolfram Sang enum i2c_slave_event event, u8 *val) 47389be323SWolfram Sang { 48389be323SWolfram Sang struct eeprom_data *eeprom = i2c_get_clientdata(client); 49389be323SWolfram Sang 50389be323SWolfram Sang switch (event) { 515b77d162SWolfram Sang case I2C_SLAVE_WRITE_RECEIVED: 5282d51481SBjörn Ardö if (eeprom->idx_write_cnt < eeprom->num_address_bytes) { 5382d51481SBjörn Ardö if (eeprom->idx_write_cnt == 0) 5482d51481SBjörn Ardö eeprom->buffer_idx = 0; 5582d51481SBjörn Ardö eeprom->buffer_idx = *val | (eeprom->buffer_idx << 8); 5682d51481SBjörn Ardö eeprom->idx_write_cnt++; 57389be323SWolfram Sang } else { 5811af27f4SBjörn Ardö if (!eeprom->read_only) { 59389be323SWolfram Sang spin_lock(&eeprom->buffer_lock); 6082d51481SBjörn Ardö eeprom->buffer[eeprom->buffer_idx++ & eeprom->address_mask] = *val; 61389be323SWolfram Sang spin_unlock(&eeprom->buffer_lock); 62389be323SWolfram Sang } 6311af27f4SBjörn Ardö } 64389be323SWolfram Sang break; 65389be323SWolfram Sang 665b77d162SWolfram Sang case I2C_SLAVE_READ_PROCESSED: 6798e982b3SWolfram Sang /* The previous byte made it to the bus, get next one */ 685b77d162SWolfram Sang eeprom->buffer_idx++; 694db7e178SGustavo A. R. Silva fallthrough; 705b77d162SWolfram Sang case I2C_SLAVE_READ_REQUESTED: 71389be323SWolfram Sang spin_lock(&eeprom->buffer_lock); 7282d51481SBjörn Ardö *val = eeprom->buffer[eeprom->buffer_idx & eeprom->address_mask]; 73389be323SWolfram Sang spin_unlock(&eeprom->buffer_lock); 7498e982b3SWolfram Sang /* 7598e982b3SWolfram Sang * Do not increment buffer_idx here, because we don't know if 7698e982b3SWolfram Sang * this byte will be actually used. Read Linux I2C slave docs 7798e982b3SWolfram Sang * for details. 7898e982b3SWolfram Sang */ 79389be323SWolfram Sang break; 80389be323SWolfram Sang 81389be323SWolfram Sang case I2C_SLAVE_STOP: 825b77d162SWolfram Sang case I2C_SLAVE_WRITE_REQUESTED: 8382d51481SBjörn Ardö eeprom->idx_write_cnt = 0; 84389be323SWolfram Sang break; 85389be323SWolfram Sang 86389be323SWolfram Sang default: 87389be323SWolfram Sang break; 88389be323SWolfram Sang } 89389be323SWolfram Sang 90389be323SWolfram Sang return 0; 91389be323SWolfram Sang } 92389be323SWolfram Sang 93389be323SWolfram Sang static ssize_t i2c_slave_eeprom_bin_read(struct file *filp, struct kobject *kobj, 94389be323SWolfram Sang struct bin_attribute *attr, char *buf, loff_t off, size_t count) 95389be323SWolfram Sang { 96389be323SWolfram Sang struct eeprom_data *eeprom; 97389be323SWolfram Sang unsigned long flags; 98389be323SWolfram Sang 996b060d8aSchenqiwu eeprom = dev_get_drvdata(kobj_to_dev(kobj)); 100389be323SWolfram Sang 101389be323SWolfram Sang spin_lock_irqsave(&eeprom->buffer_lock, flags); 102389be323SWolfram Sang memcpy(buf, &eeprom->buffer[off], count); 103389be323SWolfram Sang spin_unlock_irqrestore(&eeprom->buffer_lock, flags); 104389be323SWolfram Sang 105389be323SWolfram Sang return count; 106389be323SWolfram Sang } 107389be323SWolfram Sang 108389be323SWolfram Sang static ssize_t i2c_slave_eeprom_bin_write(struct file *filp, struct kobject *kobj, 109389be323SWolfram Sang struct bin_attribute *attr, char *buf, loff_t off, size_t count) 110389be323SWolfram Sang { 111389be323SWolfram Sang struct eeprom_data *eeprom; 112389be323SWolfram Sang unsigned long flags; 113389be323SWolfram Sang 1146b060d8aSchenqiwu eeprom = dev_get_drvdata(kobj_to_dev(kobj)); 115389be323SWolfram Sang 116389be323SWolfram Sang spin_lock_irqsave(&eeprom->buffer_lock, flags); 117389be323SWolfram Sang memcpy(&eeprom->buffer[off], buf, count); 118389be323SWolfram Sang spin_unlock_irqrestore(&eeprom->buffer_lock, flags); 119389be323SWolfram Sang 120389be323SWolfram Sang return count; 121389be323SWolfram Sang } 122389be323SWolfram Sang 123e804f0a7SBjörn Ardö static int i2c_slave_init_eeprom_data(struct eeprom_data *eeprom, struct i2c_client *client, 124e804f0a7SBjörn Ardö unsigned int size) 125e804f0a7SBjörn Ardö { 126e804f0a7SBjörn Ardö const struct firmware *fw; 127e804f0a7SBjörn Ardö const char *eeprom_data; 128e804f0a7SBjörn Ardö int ret = device_property_read_string(&client->dev, "firmware-name", &eeprom_data); 129e804f0a7SBjörn Ardö 130e804f0a7SBjörn Ardö if (!ret) { 131e804f0a7SBjörn Ardö ret = request_firmware_into_buf(&fw, eeprom_data, &client->dev, 132e804f0a7SBjörn Ardö eeprom->buffer, size); 133e804f0a7SBjörn Ardö if (ret) 134e804f0a7SBjörn Ardö return ret; 135e804f0a7SBjörn Ardö release_firmware(fw); 136e804f0a7SBjörn Ardö } else { 137e804f0a7SBjörn Ardö /* An empty eeprom typically has all bits set to 1 */ 138e804f0a7SBjörn Ardö memset(eeprom->buffer, 0xff, size); 139e804f0a7SBjörn Ardö } 140e804f0a7SBjörn Ardö return 0; 141e804f0a7SBjörn Ardö } 142e804f0a7SBjörn Ardö 143389be323SWolfram Sang static int i2c_slave_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *id) 144389be323SWolfram Sang { 145389be323SWolfram Sang struct eeprom_data *eeprom; 146389be323SWolfram Sang int ret; 1475c71ca4dSWolfram Sang unsigned int size = FIELD_GET(I2C_SLAVE_BYTELEN, id->driver_data) + 1; 14882d51481SBjörn Ardö unsigned int flag_addr16 = FIELD_GET(I2C_SLAVE_FLAG_ADDR16, id->driver_data); 149389be323SWolfram Sang 150389be323SWolfram Sang eeprom = devm_kzalloc(&client->dev, sizeof(struct eeprom_data) + size, GFP_KERNEL); 151389be323SWolfram Sang if (!eeprom) 152389be323SWolfram Sang return -ENOMEM; 153389be323SWolfram Sang 15482d51481SBjörn Ardö eeprom->num_address_bytes = flag_addr16 ? 2 : 1; 15582d51481SBjörn Ardö eeprom->address_mask = size - 1; 15611af27f4SBjörn Ardö eeprom->read_only = FIELD_GET(I2C_SLAVE_FLAG_RO, id->driver_data); 157389be323SWolfram Sang spin_lock_init(&eeprom->buffer_lock); 158389be323SWolfram Sang i2c_set_clientdata(client, eeprom); 159389be323SWolfram Sang 160e804f0a7SBjörn Ardö ret = i2c_slave_init_eeprom_data(eeprom, client, size); 161e804f0a7SBjörn Ardö if (ret) 162e804f0a7SBjörn Ardö return ret; 163e804f0a7SBjörn Ardö 164389be323SWolfram Sang sysfs_bin_attr_init(&eeprom->bin); 165389be323SWolfram Sang eeprom->bin.attr.name = "slave-eeprom"; 166389be323SWolfram Sang eeprom->bin.attr.mode = S_IRUSR | S_IWUSR; 167389be323SWolfram Sang eeprom->bin.read = i2c_slave_eeprom_bin_read; 168389be323SWolfram Sang eeprom->bin.write = i2c_slave_eeprom_bin_write; 169389be323SWolfram Sang eeprom->bin.size = size; 170389be323SWolfram Sang 171389be323SWolfram Sang ret = sysfs_create_bin_file(&client->dev.kobj, &eeprom->bin); 172389be323SWolfram Sang if (ret) 173389be323SWolfram Sang return ret; 174389be323SWolfram Sang 175389be323SWolfram Sang ret = i2c_slave_register(client, i2c_slave_eeprom_slave_cb); 176389be323SWolfram Sang if (ret) { 177389be323SWolfram Sang sysfs_remove_bin_file(&client->dev.kobj, &eeprom->bin); 178389be323SWolfram Sang return ret; 179389be323SWolfram Sang } 180389be323SWolfram Sang 181389be323SWolfram Sang return 0; 182389be323SWolfram Sang }; 183389be323SWolfram Sang 184389be323SWolfram Sang static int i2c_slave_eeprom_remove(struct i2c_client *client) 185389be323SWolfram Sang { 186389be323SWolfram Sang struct eeprom_data *eeprom = i2c_get_clientdata(client); 187389be323SWolfram Sang 188389be323SWolfram Sang i2c_slave_unregister(client); 189389be323SWolfram Sang sysfs_remove_bin_file(&client->dev.kobj, &eeprom->bin); 190389be323SWolfram Sang 191389be323SWolfram Sang return 0; 192389be323SWolfram Sang } 193389be323SWolfram Sang 194389be323SWolfram Sang static const struct i2c_device_id i2c_slave_eeprom_id[] = { 19582d51481SBjörn Ardö { "slave-24c02", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, 0) }, 19611af27f4SBjörn Ardö { "slave-24c02ro", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, I2C_SLAVE_FLAG_RO) }, 19782d51481SBjörn Ardö { "slave-24c32", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16) }, 19811af27f4SBjörn Ardö { "slave-24c32ro", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) }, 19982d51481SBjörn Ardö { "slave-24c64", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16) }, 20011af27f4SBjörn Ardö { "slave-24c64ro", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) }, 2015c71ca4dSWolfram Sang { "slave-24c512", I2C_SLAVE_DEVICE_MAGIC(524288 / 8, I2C_SLAVE_FLAG_ADDR16) }, 2025c71ca4dSWolfram Sang { "slave-24c512ro", I2C_SLAVE_DEVICE_MAGIC(524288 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) }, 203389be323SWolfram Sang { } 204389be323SWolfram Sang }; 205389be323SWolfram Sang MODULE_DEVICE_TABLE(i2c, i2c_slave_eeprom_id); 206389be323SWolfram Sang 207389be323SWolfram Sang static struct i2c_driver i2c_slave_eeprom_driver = { 208389be323SWolfram Sang .driver = { 209389be323SWolfram Sang .name = "i2c-slave-eeprom", 210389be323SWolfram Sang }, 211389be323SWolfram Sang .probe = i2c_slave_eeprom_probe, 212389be323SWolfram Sang .remove = i2c_slave_eeprom_remove, 213389be323SWolfram Sang .id_table = i2c_slave_eeprom_id, 214389be323SWolfram Sang }; 215389be323SWolfram Sang module_i2c_driver(i2c_slave_eeprom_driver); 216389be323SWolfram Sang 217389be323SWolfram Sang MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>"); 218389be323SWolfram Sang MODULE_DESCRIPTION("I2C slave mode EEPROM simulator"); 219389be323SWolfram Sang MODULE_LICENSE("GPL v2"); 220