drivers/i2c/busses/i2c-sh7760.c
Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-sh7760.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/busses/i2c-sh7760.c- Extension
.c- Size
- 13079 bytes
- Lines
- 563
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/completion.hlinux/delay.hlinux/err.hlinux/i2c.hlinux/interrupt.hlinux/ioport.hlinux/platform_device.hlinux/slab.hlinux/io.hlinux/module.hasm/clock.hasm/i2c-sh7760.h
Detected Declarations
struct cami2cfunction OUT32function IN32function sh7760_i2c_irqfunction sh7760_i2c_mrecvfunction sh7760_i2c_msendfunction sh7760_i2c_busy_checkfunction sh7760_i2c_master_xferfunction sh7760_i2c_funcfunction clockfunction sh7760_i2c_probefunction sh7760_i2c_remove
Annotated Snippet
struct cami2c {
void __iomem *iobase;
struct i2c_adapter adap;
/* message processing */
struct i2c_msg *msg;
#define IDF_SEND 1
#define IDF_RECV 2
#define IDF_STOP 4
int flags;
#define IDS_DONE 1
#define IDS_ARBLOST 2
#define IDS_NACK 4
int status;
struct completion xfer_done;
int irq;
struct resource *ioarea;
};
static inline void OUT32(struct cami2c *cam, int reg, unsigned long val)
{
__raw_writel(val, (unsigned long)cam->iobase + reg);
}
static inline unsigned long IN32(struct cami2c *cam, int reg)
{
return __raw_readl((unsigned long)cam->iobase + reg);
}
static irqreturn_t sh7760_i2c_irq(int irq, void *ptr)
{
struct cami2c *id = ptr;
struct i2c_msg *msg = id->msg;
char *data = msg->buf;
unsigned long msr, fsr, fier, len;
msr = IN32(id, I2CMSR);
fsr = IN32(id, I2CFSR);
/* arbitration lost */
if (msr & MSR_MAL) {
OUT32(id, I2CMCR, 0);
OUT32(id, I2CSCR, 0);
OUT32(id, I2CSAR, 0);
id->status |= IDS_DONE | IDS_ARBLOST;
goto out;
}
if (msr & MSR_MNR) {
/* NACK handling is very screwed up. After receiving a
* NAK IRQ one has to wait a bit before writing to any
* registers, or the ctl will lock up. After that delay
* do a normal i2c stop. Then wait at least 1 ms before
* attempting another transfer or ctl will stop working
*/
udelay(100); /* wait or risk ctl hang */
OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
OUT32(id, I2CFIER, 0);
OUT32(id, I2CMIER, MIE_MSTE);
OUT32(id, I2CSCR, 0);
OUT32(id, I2CSAR, 0);
id->status |= IDS_NACK;
msr &= ~MSR_MAT;
fsr = 0;
/* In some cases the MST bit is also set. */
}
/* i2c-stop was sent */
if (msr & MSR_MST) {
id->status |= IDS_DONE;
goto out;
}
/* i2c slave addr was sent; set to "normal" operation */
if (msr & MSR_MAT)
OUT32(id, I2CMCR, MCR_MIE);
fier = IN32(id, I2CFIER);
if (fsr & FSR_RDF) {
len = IN32(id, I2CRFDR);
if (msg->len <= len) {
if (id->flags & IDF_STOP) {
OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
OUT32(id, I2CFIER, 0);
/* manual says: wait >= 0.5 SCL times */
udelay(5);
Annotation
- Immediate include surface: `linux/completion.h`, `linux/delay.h`, `linux/err.h`, `linux/i2c.h`, `linux/interrupt.h`, `linux/ioport.h`, `linux/platform_device.h`, `linux/slab.h`.
- Detected declarations: `struct cami2c`, `function OUT32`, `function IN32`, `function sh7760_i2c_irq`, `function sh7760_i2c_mrecv`, `function sh7760_i2c_msend`, `function sh7760_i2c_busy_check`, `function sh7760_i2c_master_xfer`, `function sh7760_i2c_func`, `function clock`.
- Atlas domain: Driver Families / drivers/i2c.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.