Lines Matching +full:i2cr +full:- +full:fsi +full:- +full:master

1 // SPDX-License-Identifier: GPL-2.0
5 #include <linux/fsi.h>
11 #include "fsi-master-i2cr.h"
79 msgs[0].addr = client->addr; in i2cr_transfer()
83 msgs[1].addr = client->addr; in i2cr_transfer()
88 ret = i2c_transfer(client->adapter, msgs, 2); in i2cr_transfer()
97 return -EIO; in i2cr_transfer()
128 dev_err(&client->dev, "status:%016llx error:%016llx log:%016llx\n", status, error, in i2cr_check_status()
130 return -EREMOTEIO; in i2cr_check_status()
137 int fsi_master_i2cr_read(struct fsi_master_i2cr *i2cr, u32 addr, u64 *data) in fsi_master_i2cr_read() argument
142 mutex_lock(&i2cr->lock); in fsi_master_i2cr_read()
144 ret = i2cr_transfer(i2cr->client, command, data); in fsi_master_i2cr_read()
148 ret = i2cr_check_status(i2cr->client); in fsi_master_i2cr_read()
152 trace_i2cr_read(i2cr->client, command, data); in fsi_master_i2cr_read()
155 mutex_unlock(&i2cr->lock); in fsi_master_i2cr_read()
160 int fsi_master_i2cr_write(struct fsi_master_i2cr *i2cr, u32 addr, u64 data) in fsi_master_i2cr_write() argument
168 mutex_lock(&i2cr->lock); in fsi_master_i2cr_write()
170 ret = i2c_master_send(i2cr->client, (const char *)buf, sizeof(buf)); in fsi_master_i2cr_write()
172 ret = i2cr_check_status(i2cr->client); in fsi_master_i2cr_write()
174 trace_i2cr_write(i2cr->client, buf[0], data); in fsi_master_i2cr_write()
176 trace_i2cr_i2c_error(i2cr->client, buf[0], ret); in fsi_master_i2cr_write()
179 ret = -EIO; in fsi_master_i2cr_write()
182 mutex_unlock(&i2cr->lock); in fsi_master_i2cr_write()
187 static int i2cr_read(struct fsi_master *master, int link, uint8_t id, uint32_t addr, void *val, in i2cr_read() argument
190 struct fsi_master_i2cr *i2cr = container_of(master, struct fsi_master_i2cr, master); in i2cr_read() local
196 return -EINVAL; in i2cr_read()
199 * The I2CR doesn't have CFAM or FSI slave address space - only the in i2cr_read()
200 * engines. In order for this to work with the FSI core, we need to in i2cr_read()
205 if (addr > sizeof(i2cr_cfam) - 4) in i2cr_read()
206 addr = (addr & 0x3) + (sizeof(i2cr_cfam) - 4); in i2cr_read()
212 ret = fsi_master_i2cr_read(i2cr, I2CR_ADDRESS_CFAM(addr), &data); in i2cr_read()
217 * FSI core expects up to 4 bytes BE back, while I2CR replied with LE in i2cr_read()
221 ((u8 *)val)[i] = ((u8 *)&data)[7 - i]; in i2cr_read()
226 static int i2cr_write(struct fsi_master *master, int link, uint8_t id, uint32_t addr, in i2cr_write() argument
229 struct fsi_master_i2cr *i2cr = container_of(master, struct fsi_master_i2cr, master); in i2cr_write() local
234 return -EINVAL; in i2cr_write()
236 /* I2CR writes to CFAM or FSI slave address are a successful no-op. */ in i2cr_write()
241 * FSI core passes up to 4 bytes BE, while the I2CR expects LE bytes on in i2cr_write()
245 ((u8 *)&data)[7 - i] = ((u8 *)val)[i]; in i2cr_write()
247 return fsi_master_i2cr_write(i2cr, I2CR_ADDRESS_CFAM(addr), data); in i2cr_write()
252 struct fsi_master_i2cr *i2cr = to_fsi_master_i2cr(to_fsi_master(dev)); in i2cr_release() local
254 of_node_put(dev->of_node); in i2cr_release()
256 kfree(i2cr); in i2cr_release()
261 struct fsi_master_i2cr *i2cr; in i2cr_probe() local
264 i2cr = kzalloc(sizeof(*i2cr), GFP_KERNEL); in i2cr_probe()
265 if (!i2cr) in i2cr_probe()
266 return -ENOMEM; in i2cr_probe()
268 /* Only one I2CR on any given I2C bus (fixed I2C device address) */ in i2cr_probe()
269 i2cr->master.idx = client->adapter->nr; in i2cr_probe()
270 dev_set_name(&i2cr->master.dev, "i2cr%d", i2cr->master.idx); in i2cr_probe()
271 i2cr->master.dev.parent = &client->dev; in i2cr_probe()
272 i2cr->master.dev.of_node = of_node_get(dev_of_node(&client->dev)); in i2cr_probe()
273 i2cr->master.dev.release = i2cr_release; in i2cr_probe()
275 i2cr->master.n_links = 1; in i2cr_probe()
276 i2cr->master.read = i2cr_read; in i2cr_probe()
277 i2cr->master.write = i2cr_write; in i2cr_probe()
279 mutex_init(&i2cr->lock); in i2cr_probe()
280 i2cr->client = client; in i2cr_probe()
282 ret = fsi_master_register(&i2cr->master); in i2cr_probe()
286 i2c_set_clientdata(client, i2cr); in i2cr_probe()
292 struct fsi_master_i2cr *i2cr = i2c_get_clientdata(client); in i2cr_remove() local
294 fsi_master_unregister(&i2cr->master); in i2cr_remove()
298 { .compatible = "ibm,i2cr-fsi-master" },
307 .name = "fsi-master-i2cr",
315 MODULE_DESCRIPTION("IBM I2C Responder virtual FSI master driver");