drivers/i2c/busses/i2c-cp2615.c
Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-cp2615.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/busses/i2c-cp2615.c- Extension
.c- Size
- 8209 bytes
- Lines
- 339
- Domain
- Driver Families
- Bucket
- drivers/i2c
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/errno.hlinux/i2c.hlinux/kernel.hlinux/module.hlinux/string.hlinux/usb.h
Detected Declarations
enum cp2615_iop_msg_typeenum cp2615_i2c_statusfunction cp2615_init_iop_msgfunction cp2615_init_i2c_msgfunction cp2615_check_statusfunction cp2615_i2c_sendfunction cp2615_i2c_recvfunction cp2615_check_iopfunction cp2615_i2c_xferfunction cp2615_i2c_funcfunction cp2615_i2c_disconnectfunction cp2615_i2c_probe
Annotated Snippet
if (msg->flags & I2C_M_RD) {
i2c_w.read_len = msg->len;
i2c_w.write_len = 0;
} else {
i2c_w.read_len = 0;
i2c_w.write_len = msg->len;
memcpy(&i2c_w.data, msg->buf, i2c_w.write_len);
}
ret = cp2615_i2c_send(usbif, &i2c_w);
if (ret)
break;
ret = cp2615_i2c_recv(usbif, i2c_w.tag, msg->buf);
}
if (ret < 0)
return ret;
return i;
}
static u32
cp2615_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static const struct i2c_algorithm cp2615_i2c_algo = {
.xfer = cp2615_i2c_xfer,
.functionality = cp2615_i2c_func,
};
/*
* This chip has some limitations: one is that the USB endpoint
* can only receive 64 bytes/transfer, that leaves 54 bytes for
* the I2C transfer. On top of that, EITHER read_len OR write_len
* may be zero, but not both. If both are non-zero, the adapter
* issues a write followed by a read. And the chip does not
* support repeated START between the write and read phases.
*/
static struct i2c_adapter_quirks cp2615_i2c_quirks = {
.max_write_len = MAX_I2C_SIZE,
.max_read_len = MAX_I2C_SIZE,
.flags = I2C_AQ_COMB_WRITE_THEN_READ | I2C_AQ_NO_ZERO_LEN | I2C_AQ_NO_REP_START,
.max_comb_1st_msg_len = MAX_I2C_SIZE,
.max_comb_2nd_msg_len = MAX_I2C_SIZE
};
static void cp2615_i2c_disconnect(struct usb_interface *usbif)
{
struct i2c_adapter *adap = usb_get_intfdata(usbif);
usb_set_intfdata(usbif, NULL);
i2c_del_adapter(adap);
}
static int
cp2615_i2c_probe(struct usb_interface *usbif, const struct usb_device_id *id)
{
int ret = 0;
struct i2c_adapter *adap;
struct usb_device *usbdev = interface_to_usbdev(usbif);
ret = usb_set_interface(usbdev, IOP_IFN, IOP_ALTSETTING);
if (ret)
return ret;
ret = cp2615_check_iop(usbif);
if (ret)
return ret;
adap = devm_kzalloc(&usbif->dev, sizeof(struct i2c_adapter), GFP_KERNEL);
if (!adap)
return -ENOMEM;
if (!usbdev->serial)
return -EINVAL;
strscpy(adap->name, usbdev->serial, sizeof(adap->name));
adap->owner = THIS_MODULE;
adap->dev.parent = &usbif->dev;
adap->dev.of_node = usbif->dev.of_node;
adap->timeout = HZ;
adap->algo = &cp2615_i2c_algo;
adap->quirks = &cp2615_i2c_quirks;
adap->algo_data = usbif;
ret = i2c_add_adapter(adap);
if (ret)
return ret;
usb_set_intfdata(usbif, adap);
return 0;
Annotation
- Immediate include surface: `linux/errno.h`, `linux/i2c.h`, `linux/kernel.h`, `linux/module.h`, `linux/string.h`, `linux/usb.h`.
- Detected declarations: `enum cp2615_iop_msg_type`, `enum cp2615_i2c_status`, `function cp2615_init_iop_msg`, `function cp2615_init_i2c_msg`, `function cp2615_check_status`, `function cp2615_i2c_send`, `function cp2615_i2c_recv`, `function cp2615_check_iop`, `function cp2615_i2c_xfer`, `function cp2615_i2c_func`.
- Atlas domain: Driver Families / drivers/i2c.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.