drivers/i2c/busses/i2c-sis5595.c
Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-sis5595.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/busses/i2c-sis5595.c- Extension
.c- Size
- 11250 bytes
- Lines
- 423
- 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/init.hlinux/i2c.hlinux/acpi.hlinux/io.h
Detected Declarations
function sis5595_readfunction sis5595_writefunction sis5595_setupfunction sis5595_transactionfunction sis5595_accessfunction sis5595_funcfunction sis5595_probefunction i2c_sis5595_initfunction i2c_sis5595_exitmodule init i2c_sis5595_init
Annotated Snippet
static struct pci_driver sis5595_driver;
static unsigned short sis5595_base;
static struct pci_dev *sis5595_pdev;
static u8 sis5595_read(u8 reg)
{
outb(reg, sis5595_base + SMB_INDEX);
return inb(sis5595_base + SMB_DAT);
}
static void sis5595_write(u8 reg, u8 data)
{
outb(reg, sis5595_base + SMB_INDEX);
outb(data, sis5595_base + SMB_DAT);
}
static int sis5595_setup(struct pci_dev *SIS5595_dev)
{
u16 a;
u8 val;
int *i;
int retval;
/* Look for imposters */
for (i = blacklist; *i != 0; i++) {
struct pci_dev *dev;
dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL);
if (dev) {
dev_err(&SIS5595_dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
pci_dev_put(dev);
return -ENODEV;
}
}
/* Determine the address of the SMBus areas */
pci_read_config_word(SIS5595_dev, ACPI_BASE, &sis5595_base);
if (sis5595_base == 0 && force_addr == 0) {
dev_err(&SIS5595_dev->dev, "ACPI base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
return -ENODEV;
}
if (force_addr)
sis5595_base = force_addr & ~(SIS5595_EXTENT - 1);
dev_dbg(&SIS5595_dev->dev, "ACPI Base address: %04x\n", sis5595_base);
/* NB: We grab just the two SMBus registers here, but this may still
* interfere with ACPI :-( */
retval = acpi_check_region(sis5595_base + SMB_INDEX, 2,
sis5595_driver.name);
if (retval)
return retval;
if (!request_region(sis5595_base + SMB_INDEX, 2,
sis5595_driver.name)) {
dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1);
return -ENODEV;
}
if (force_addr) {
dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base);
retval = pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base);
if (retval != PCIBIOS_SUCCESSFUL)
goto error;
retval = pci_read_config_word(SIS5595_dev, ACPI_BASE, &a);
if (retval != PCIBIOS_SUCCESSFUL)
goto error;
if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) {
/* doesn't work for some chips! */
dev_err(&SIS5595_dev->dev, "force address failed - not supported?\n");
goto error;
}
}
retval = pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val);
if (retval != PCIBIOS_SUCCESSFUL)
goto error;
if ((val & 0x80) == 0) {
dev_info(&SIS5595_dev->dev, "enabling ACPI\n");
retval = pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80);
if (retval != PCIBIOS_SUCCESSFUL)
goto error;
retval = pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val);
if (retval != PCIBIOS_SUCCESSFUL)
goto error;
if ((val & 0x80) == 0) {
/* doesn't work for some chips? */
dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n");
goto error;
}
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/delay.h`, `linux/pci.h`, `linux/ioport.h`, `linux/init.h`, `linux/i2c.h`, `linux/acpi.h`.
- Detected declarations: `function sis5595_read`, `function sis5595_write`, `function sis5595_setup`, `function sis5595_transaction`, `function sis5595_access`, `function sis5595_func`, `function sis5595_probe`, `function i2c_sis5595_init`, `function i2c_sis5595_exit`, `module init i2c_sis5595_init`.
- 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.