Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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