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 * 8389be323SWolfram Sang * Because most IP blocks can only detect one I2C slave address anyhow, this 9389be323SWolfram Sang * driver does not support simulating EEPROM types which take more than one 10389be323SWolfram Sang * address. It is prepared to simulate bigger EEPROMs with an internal 16 bit 11389be323SWolfram Sang * pointer, yet implementation is deferred until the need actually arises. 12389be323SWolfram Sang */ 13389be323SWolfram Sang 14fe050f99SBjörn Ardö /* 15fe050f99SBjörn Ardö * FIXME: What to do if only 8 bits of a 16 bit address are sent? 16fe050f99SBjörn Ardö * The ST-M24C64 sends only 0xff then. Needs verification with other 17fe050f99SBjörn Ardö * EEPROMs, though. We currently use the 8 bit as a valid address. 18fe050f99SBjörn Ardö */ 19fe050f99SBjörn Ardö 2082d51481SBjörn Ardö #include <linux/bitfield.h> 21e804f0a7SBjörn Ardö #include <linux/firmware.h> 22389be323SWolfram Sang #include <linux/i2c.h> 23389be323SWolfram Sang #include <linux/init.h> 24389be323SWolfram Sang #include <linux/module.h> 25389be323SWolfram Sang #include <linux/of.h> 26389be323SWolfram Sang #include <linux/slab.h> 27389be323SWolfram Sang #include <linux/spinlock.h> 28389be323SWolfram Sang #include <linux/sysfs.h> 29389be323SWolfram Sang 30389be323SWolfram Sang struct eeprom_data { 31389be323SWolfram Sang struct bin_attribute bin; 32389be323SWolfram Sang spinlock_t buffer_lock; 3382d51481SBjörn Ardö u16 buffer_idx; 3482d51481SBjörn Ardö u16 address_mask; 3582d51481SBjörn Ardö u8 num_address_bytes; 3682d51481SBjörn Ardö u8 idx_write_cnt; 3711af27f4SBjörn Ardö bool read_only; 38389be323SWolfram Sang u8 buffer[]; 39389be323SWolfram Sang }; 40389be323SWolfram Sang 4182d51481SBjörn Ardö #define I2C_SLAVE_BYTELEN GENMASK(15, 0) 4282d51481SBjörn Ardö #define I2C_SLAVE_FLAG_ADDR16 BIT(16) 4311af27f4SBjörn Ardö #define I2C_SLAVE_FLAG_RO BIT(17) 4482d51481SBjörn Ardö #define I2C_SLAVE_DEVICE_MAGIC(_len, _flags) ((_flags) | (_len)) 4582d51481SBjörn Ardö 46389be323SWolfram Sang static int i2c_slave_eeprom_slave_cb(struct i2c_client *client, 47389be323SWolfram Sang enum i2c_slave_event event, u8 *val) 48389be323SWolfram Sang { 49389be323SWolfram Sang struct eeprom_data *eeprom = i2c_get_clientdata(client); 50389be323SWolfram Sang 51389be323SWolfram Sang switch (event) { 525b77d162SWolfram Sang case I2C_SLAVE_WRITE_RECEIVED: 5382d51481SBjörn Ardö if (eeprom->idx_write_cnt < eeprom->num_address_bytes) { 5482d51481SBjörn Ardö if (eeprom->idx_write_cnt == 0) 5582d51481SBjörn Ardö eeprom->buffer_idx = 0; 5682d51481SBjörn Ardö eeprom->buffer_idx = *val | (eeprom->buffer_idx << 8); 5782d51481SBjörn Ardö eeprom->idx_write_cnt++; 58389be323SWolfram Sang } else { 5911af27f4SBjörn Ardö if (!eeprom->read_only) { 60389be323SWolfram Sang spin_lock(&eeprom->buffer_lock); 6182d51481SBjörn Ardö eeprom->buffer[eeprom->buffer_idx++ & eeprom->address_mask] = *val; 62389be323SWolfram Sang spin_unlock(&eeprom->buffer_lock); 63389be323SWolfram Sang } 6411af27f4SBjörn Ardö } 65389be323SWolfram Sang break; 66389be323SWolfram Sang 675b77d162SWolfram Sang case I2C_SLAVE_READ_PROCESSED: 6898e982b3SWolfram Sang /* The previous byte made it to the bus, get next one */ 695b77d162SWolfram Sang eeprom->buffer_idx++; 705b77d162SWolfram Sang /* fallthrough */ 715b77d162SWolfram Sang case I2C_SLAVE_READ_REQUESTED: 72389be323SWolfram Sang spin_lock(&eeprom->buffer_lock); 7382d51481SBjörn Ardö *val = eeprom->buffer[eeprom->buffer_idx & eeprom->address_mask]; 74389be323SWolfram Sang spin_unlock(&eeprom->buffer_lock); 7598e982b3SWolfram Sang /* 7698e982b3SWolfram Sang * Do not increment buffer_idx here, because we don't know if 7798e982b3SWolfram Sang * this byte will be actually used. Read Linux I2C slave docs 7898e982b3SWolfram Sang * for details. 7998e982b3SWolfram Sang */ 80389be323SWolfram Sang break; 81389be323SWolfram Sang 82389be323SWolfram Sang case I2C_SLAVE_STOP: 835b77d162SWolfram Sang case I2C_SLAVE_WRITE_REQUESTED: 8482d51481SBjörn Ardö eeprom->idx_write_cnt = 0; 85389be323SWolfram Sang break; 86389be323SWolfram Sang 87389be323SWolfram Sang default: 88389be323SWolfram Sang break; 89389be323SWolfram Sang } 90389be323SWolfram Sang 91389be323SWolfram Sang return 0; 92389be323SWolfram Sang } 93389be323SWolfram Sang 94389be323SWolfram Sang static ssize_t i2c_slave_eeprom_bin_read(struct file *filp, struct kobject *kobj, 95389be323SWolfram Sang struct bin_attribute *attr, char *buf, loff_t off, size_t count) 96389be323SWolfram Sang { 97389be323SWolfram Sang struct eeprom_data *eeprom; 98389be323SWolfram Sang unsigned long flags; 99389be323SWolfram Sang 1006b060d8aSchenqiwu eeprom = dev_get_drvdata(kobj_to_dev(kobj)); 101389be323SWolfram Sang 102389be323SWolfram Sang spin_lock_irqsave(&eeprom->buffer_lock, flags); 103389be323SWolfram Sang memcpy(buf, &eeprom->buffer[off], count); 104389be323SWolfram Sang spin_unlock_irqrestore(&eeprom->buffer_lock, flags); 105389be323SWolfram Sang 106389be323SWolfram Sang return count; 107389be323SWolfram Sang } 108389be323SWolfram Sang 109389be323SWolfram Sang static ssize_t i2c_slave_eeprom_bin_write(struct file *filp, struct kobject *kobj, 110389be323SWolfram Sang struct bin_attribute *attr, char *buf, loff_t off, size_t count) 111389be323SWolfram Sang { 112389be323SWolfram Sang struct eeprom_data *eeprom; 113389be323SWolfram Sang unsigned long flags; 114389be323SWolfram Sang 1156b060d8aSchenqiwu eeprom = dev_get_drvdata(kobj_to_dev(kobj)); 116389be323SWolfram Sang 117389be323SWolfram Sang spin_lock_irqsave(&eeprom->buffer_lock, flags); 118389be323SWolfram Sang memcpy(&eeprom->buffer[off], buf, count); 119389be323SWolfram Sang spin_unlock_irqrestore(&eeprom->buffer_lock, flags); 120389be323SWolfram Sang 121389be323SWolfram Sang return count; 122389be323SWolfram Sang } 123389be323SWolfram Sang 124e804f0a7SBjörn Ardö static int i2c_slave_init_eeprom_data(struct eeprom_data *eeprom, struct i2c_client *client, 125e804f0a7SBjörn Ardö unsigned int size) 126e804f0a7SBjörn Ardö { 127e804f0a7SBjörn Ardö const struct firmware *fw; 128e804f0a7SBjörn Ardö const char *eeprom_data; 129e804f0a7SBjörn Ardö int ret = device_property_read_string(&client->dev, "firmware-name", &eeprom_data); 130e804f0a7SBjörn Ardö 131e804f0a7SBjörn Ardö if (!ret) { 132e804f0a7SBjörn Ardö ret = request_firmware_into_buf(&fw, eeprom_data, &client->dev, 133e804f0a7SBjörn Ardö eeprom->buffer, size); 134e804f0a7SBjörn Ardö if (ret) 135e804f0a7SBjörn Ardö return ret; 136e804f0a7SBjörn Ardö release_firmware(fw); 137e804f0a7SBjörn Ardö } else { 138e804f0a7SBjörn Ardö /* An empty eeprom typically has all bits set to 1 */ 139e804f0a7SBjörn Ardö memset(eeprom->buffer, 0xff, size); 140e804f0a7SBjörn Ardö } 141e804f0a7SBjörn Ardö return 0; 142e804f0a7SBjörn Ardö } 143e804f0a7SBjörn Ardö 144389be323SWolfram Sang static int i2c_slave_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *id) 145389be323SWolfram Sang { 146389be323SWolfram Sang struct eeprom_data *eeprom; 147389be323SWolfram Sang int ret; 14882d51481SBjörn Ardö unsigned int size = FIELD_GET(I2C_SLAVE_BYTELEN, id->driver_data); 14982d51481SBjörn Ardö unsigned int flag_addr16 = FIELD_GET(I2C_SLAVE_FLAG_ADDR16, id->driver_data); 150389be323SWolfram Sang 151389be323SWolfram Sang eeprom = devm_kzalloc(&client->dev, sizeof(struct eeprom_data) + size, GFP_KERNEL); 152389be323SWolfram Sang if (!eeprom) 153389be323SWolfram Sang return -ENOMEM; 154389be323SWolfram Sang 15582d51481SBjörn Ardö eeprom->idx_write_cnt = 0; 15682d51481SBjörn Ardö eeprom->num_address_bytes = flag_addr16 ? 2 : 1; 15782d51481SBjörn Ardö eeprom->address_mask = size - 1; 15811af27f4SBjörn Ardö eeprom->read_only = FIELD_GET(I2C_SLAVE_FLAG_RO, id->driver_data); 159389be323SWolfram Sang spin_lock_init(&eeprom->buffer_lock); 160389be323SWolfram Sang i2c_set_clientdata(client, eeprom); 161389be323SWolfram Sang 162e804f0a7SBjörn Ardö ret = i2c_slave_init_eeprom_data(eeprom, client, size); 163e804f0a7SBjörn Ardö if (ret) 164e804f0a7SBjörn Ardö return ret; 165e804f0a7SBjörn Ardö 166389be323SWolfram Sang sysfs_bin_attr_init(&eeprom->bin); 167389be323SWolfram Sang eeprom->bin.attr.name = "slave-eeprom"; 168389be323SWolfram Sang eeprom->bin.attr.mode = S_IRUSR | S_IWUSR; 169389be323SWolfram Sang eeprom->bin.read = i2c_slave_eeprom_bin_read; 170389be323SWolfram Sang eeprom->bin.write = i2c_slave_eeprom_bin_write; 171389be323SWolfram Sang eeprom->bin.size = size; 172389be323SWolfram Sang 173389be323SWolfram Sang ret = sysfs_create_bin_file(&client->dev.kobj, &eeprom->bin); 174389be323SWolfram Sang if (ret) 175389be323SWolfram Sang return ret; 176389be323SWolfram Sang 177389be323SWolfram Sang ret = i2c_slave_register(client, i2c_slave_eeprom_slave_cb); 178389be323SWolfram Sang if (ret) { 179389be323SWolfram Sang sysfs_remove_bin_file(&client->dev.kobj, &eeprom->bin); 180389be323SWolfram Sang return ret; 181389be323SWolfram Sang } 182389be323SWolfram Sang 183389be323SWolfram Sang return 0; 184389be323SWolfram Sang }; 185389be323SWolfram Sang 186389be323SWolfram Sang static int i2c_slave_eeprom_remove(struct i2c_client *client) 187389be323SWolfram Sang { 188389be323SWolfram Sang struct eeprom_data *eeprom = i2c_get_clientdata(client); 189389be323SWolfram Sang 190389be323SWolfram Sang i2c_slave_unregister(client); 191389be323SWolfram Sang sysfs_remove_bin_file(&client->dev.kobj, &eeprom->bin); 192389be323SWolfram Sang 193389be323SWolfram Sang return 0; 194389be323SWolfram Sang } 195389be323SWolfram Sang 196389be323SWolfram Sang static const struct i2c_device_id i2c_slave_eeprom_id[] = { 19782d51481SBjörn Ardö { "slave-24c02", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, 0) }, 19811af27f4SBjörn Ardö { "slave-24c02ro", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, I2C_SLAVE_FLAG_RO) }, 19982d51481SBjörn Ardö { "slave-24c32", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16) }, 20011af27f4SBjörn Ardö { "slave-24c32ro", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) }, 20182d51481SBjörn Ardö { "slave-24c64", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16) }, 20211af27f4SBjörn Ardö { "slave-24c64ro", I2C_SLAVE_DEVICE_MAGIC(65536 / 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