File indexing completed on 2025-05-11 08:24:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifdef HAVE_CONFIG_H
0016 #include "config.h"
0017 #endif
0018
0019 #include <dev/i2c/i2c.h>
0020 #include <dev/i2c/fpga-i2c-slave.h>
0021
0022 typedef struct {
0023 i2c_dev base;
0024 uint16_t address;
0025 size_t size;
0026 } fpga_i2c_slave;
0027
0028 static ssize_t
0029 fpga_i2c_slave_read(i2c_dev* base, void* buf, size_t n, off_t offset)
0030 {
0031 fpga_i2c_slave* dev = (fpga_i2c_slave*) base;
0032 off_t avail = dev->size - offset;
0033 uint8_t* in = buf;
0034 size_t todo;
0035
0036 if (avail <= 0) {
0037 return 0;
0038 }
0039
0040 if (n > avail) {
0041 n = (size_t) avail;
0042 }
0043
0044 todo = n;
0045
0046 while (todo > 0) {
0047
0048
0049
0050
0051 uint16_t cur = (uint16_t) (todo < 255 ? todo : 255);
0052 i2c_msg msgs = {
0053 .addr = dev->base.address,
0054 .flags = I2C_M_RD,
0055 .buf = in,
0056 .len = cur
0057 };
0058 int err;
0059 err = i2c_bus_transfer(dev->base.bus, &msgs, 1);
0060 if (err != 0) {
0061 return err;
0062 }
0063 todo -= cur;
0064 in += cur;
0065 }
0066
0067 return (ssize_t) n;
0068 }
0069
0070 static ssize_t
0071 fpga_i2c_slave_write(i2c_dev* base, const void* buf, size_t n, off_t offset)
0072 {
0073 fpga_i2c_slave* dev = (fpga_i2c_slave*) base;
0074 off_t avail = dev->size - offset;
0075 const uint8_t* out = buf;
0076 size_t todo;
0077
0078 if (avail <= 0) {
0079 return 0;
0080 }
0081
0082 if (n > avail) {
0083 n = (size_t) avail;
0084 }
0085
0086 todo = n;
0087
0088 while (todo > 0) {
0089
0090
0091
0092
0093 uint16_t cur = (uint16_t) (todo < 255 ? todo : 255);
0094 i2c_msg msgs = {
0095 .addr = dev->base.address,
0096 .flags = 0,
0097 .buf = RTEMS_DECONST(uint8_t*, out),
0098 .len = cur
0099 };
0100 int err;
0101 err = i2c_bus_transfer(dev->base.bus, &msgs, 1);
0102 if (err != 0) {
0103 return err;
0104 }
0105 todo -= cur;
0106 out += cur;
0107 }
0108
0109 return (ssize_t) n;
0110 }
0111
0112 int
0113 i2c_dev_register_fpga_i2c_slave(const char* bus_path,
0114 const char* dev_path,
0115 uint16_t address,
0116 size_t size)
0117
0118 {
0119 fpga_i2c_slave* dev;
0120
0121 dev = (fpga_i2c_slave*)
0122 i2c_dev_alloc_and_init(sizeof(*dev), bus_path, address);
0123 if (dev == NULL) {
0124 return -1;
0125 }
0126
0127 dev->base.read = fpga_i2c_slave_read;
0128 dev->base.write = fpga_i2c_slave_write;
0129 dev->size = size;
0130
0131 return i2c_dev_register(&dev->base, dev_path);
0132 }