drivers/i2c/busses/i2c-sis630.c
Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-sis630.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/busses/i2c-sis630.c- Extension
.c- Size
- 14425 bytes
- Lines
- 555
- Domain
- Driver Families
- Bucket
- drivers/i2c
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/delay.hlinux/pci.hlinux/ioport.hlinux/i2c.hlinux/acpi.hlinux/io.h
Detected Declarations
function sis630_readfunction sis630_writefunction sis630_transaction_startfunction sis630_transaction_waitfunction sis630_transaction_endfunction sis630_transactionfunction sis630_block_datafunction sis630_accessfunction sis630_funcfunction sis630_setupfunction pci_write_config_bytefunction sis630_probefunction sis630_remove
Annotated Snippet
static struct pci_driver sis630_driver;
/* insmod parameters */
static bool high_clock;
static bool force;
module_param(high_clock, bool, 0);
MODULE_PARM_DESC(high_clock,
"Set Host Master Clock to 56KHz (default 14KHz) (SIS630/730 only).");
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!");
/* SMBus base address */
static unsigned short smbus_base;
/* supported chips */
static int supported[] = {
PCI_DEVICE_ID_SI_630,
PCI_DEVICE_ID_SI_730,
PCI_DEVICE_ID_SI_760,
0 /* terminates the list */
};
static inline u8 sis630_read(u8 reg)
{
return inb(smbus_base + reg);
}
static inline void sis630_write(u8 reg, u8 data)
{
outb(data, smbus_base + reg);
}
static int sis630_transaction_start(struct i2c_adapter *adap, int size,
u8 *oldclock)
{
int temp;
/* Make sure the SMBus host is ready to start transmitting. */
temp = sis630_read(SMB_CNT);
if ((temp & (SMB_PROBE | SMB_HOSTBUSY)) != 0x00) {
dev_dbg(&adap->dev, "SMBus busy (%02x). Resetting...\n", temp);
/* kill smbus transaction */
sis630_write(SMBHOST_CNT, SMB_KILL);
temp = sis630_read(SMB_CNT);
if (temp & (SMB_PROBE | SMB_HOSTBUSY)) {
dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
return -EBUSY;
} else {
dev_dbg(&adap->dev, "Successful!\n");
}
}
/* save old clock, so we can prevent machine for hung */
*oldclock = sis630_read(SMB_CNT);
dev_dbg(&adap->dev, "saved clock 0x%02x\n", *oldclock);
/* disable timeout interrupt,
* set Host Master Clock to 56KHz if requested */
if (high_clock)
sis630_write(SMB_CNT, SMBCLK_SEL);
else
sis630_write(SMB_CNT, (*oldclock & ~MSTO_EN));
/* clear all sticky bits */
temp = sis630_read(SMB_STS);
sis630_write(SMB_STS, temp & 0x1e);
/* start the transaction by setting bit 4 and size */
sis630_write(SMBHOST_CNT, SMB_START | (size & 0x07));
return 0;
}
static int sis630_transaction_wait(struct i2c_adapter *adap, int size)
{
int temp, result = 0, timeout = 0;
/* We will always wait for a fraction of a second! */
do {
msleep(1);
temp = sis630_read(SMB_STS);
/* check if block transmitted */
if (size == SIS630_BLOCK_DATA && (temp & BYTE_DONE_STS))
break;
} while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT));
/* If the SMBus is still busy, we give up */
if (timeout > MAX_TIMEOUT) {
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/delay.h`, `linux/pci.h`, `linux/ioport.h`, `linux/i2c.h`, `linux/acpi.h`, `linux/io.h`.
- Detected declarations: `function sis630_read`, `function sis630_write`, `function sis630_transaction_start`, `function sis630_transaction_wait`, `function sis630_transaction_end`, `function sis630_transaction`, `function sis630_block_data`, `function sis630_access`, `function sis630_func`, `function sis630_setup`.
- Atlas domain: Driver Families / drivers/i2c.
- Implementation status: pattern 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.