drivers/media/common/saa7146/saa7146_i2c.c
Source file repositories/reference/linux-study-clean/drivers/media/common/saa7146/saa7146_i2c.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/common/saa7146/saa7146_i2c.c- Extension
.c- Size
- 12585 bytes
- Lines
- 422
- Domain
- Driver Families
- Bucket
- drivers/media
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
media/drv-intf/saa7146_vv.h
Detected Declarations
function saa7146_i2c_funcfunction saa7146_i2c_statusfunction saa7146_i2c_msg_preparefunction saa7146_i2c_msg_cleanupfunction saa7146_i2c_resetfunction badlyfunction saa7146_i2c_transferfunction saa7146_i2c_xferfunction saa7146_i2c_adapter_prepare
Annotated Snippet
if (timeout == -ERESTARTSYS || dev->i2c_op) {
SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
if (timeout == -ERESTARTSYS)
/* a signal arrived */
return -ERESTARTSYS;
pr_warn("%s %s [irq]: timed out waiting for end of xfer\n",
dev->name, __func__);
return -EIO;
}
status = saa7146_read(dev, I2C_STATUS);
} else {
saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword));
saa7146_write(dev, MC2, (MASK_00 | MASK_16));
/* do not poll for i2c-status before upload is complete */
timeout = jiffies + HZ/100 + 1; /* 10ms */
while(1) {
mc2 = (saa7146_read(dev, MC2) & 0x1);
if( 0 != mc2 ) {
break;
}
if (time_after(jiffies,timeout)) {
pr_warn("%s %s: timed out waiting for MC2\n",
dev->name, __func__);
return -EIO;
}
}
/* wait until we get a transfer done or error */
timeout = jiffies + HZ/100 + 1; /* 10ms */
/* first read usually delivers bogus results... */
saa7146_i2c_status(dev);
while(1) {
status = saa7146_i2c_status(dev);
if ((status & 0x3) != 1)
break;
if (time_after(jiffies,timeout)) {
/* this is normal when probing the bus
* (no answer from nonexisistant device...)
*/
pr_warn("%s %s [poll]: timed out waiting for end of xfer\n",
dev->name, __func__);
return -EIO;
}
if (++trial < 50 && short_delay)
udelay(10);
else
msleep(1);
}
}
/* give a detailed status report */
if ( 0 != (status & (SAA7146_I2C_SPERR | SAA7146_I2C_APERR |
SAA7146_I2C_DTERR | SAA7146_I2C_DRERR |
SAA7146_I2C_AL | SAA7146_I2C_ERR |
SAA7146_I2C_BUSY)) ) {
if ( 0 == (status & SAA7146_I2C_ERR) ||
0 == (status & SAA7146_I2C_BUSY) ) {
/* it may take some time until ERR goes high - ignore */
DEB_I2C("unexpected i2c status %04x\n", status);
}
if( 0 != (status & SAA7146_I2C_SPERR) ) {
DEB_I2C("error due to invalid start/stop condition\n");
}
if( 0 != (status & SAA7146_I2C_DTERR) ) {
DEB_I2C("error in data transmission\n");
}
if( 0 != (status & SAA7146_I2C_DRERR) ) {
DEB_I2C("error when receiving data\n");
}
if( 0 != (status & SAA7146_I2C_AL) ) {
DEB_I2C("error because arbitration lost\n");
}
/* we handle address-errors here */
if( 0 != (status & SAA7146_I2C_APERR) ) {
DEB_I2C("error in address phase\n");
return -EREMOTEIO;
}
return -EIO;
}
/* read back data, just in case we were reading ... */
*dword = cpu_to_le32(saa7146_read(dev, I2C_TRANSFER));
DEB_I2C("after: 0x%08x\n", *dword);
Annotation
- Immediate include surface: `media/drv-intf/saa7146_vv.h`.
- Detected declarations: `function saa7146_i2c_func`, `function saa7146_i2c_status`, `function saa7146_i2c_msg_prepare`, `function saa7146_i2c_msg_cleanup`, `function saa7146_i2c_reset`, `function badly`, `function saa7146_i2c_transfer`, `function saa7146_i2c_xfer`, `function saa7146_i2c_adapter_prepare`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.