drivers/i2c/busses/i2c-amd8111.c

Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-amd8111.c

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-amd8111.c
Extension
.c
Size
11687 bytes
Lines
479
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static struct pci_driver amd8111_driver;

/*
 * AMD PCI control registers definitions.
 */

#define AMD_PCI_MISC	0x48

#define AMD_PCI_MISC_SCI	0x04	/* deliver SCI */
#define AMD_PCI_MISC_INT	0x02	/* deliver PCI IRQ */
#define AMD_PCI_MISC_SPEEDUP	0x01	/* 16x clock speedup */

/*
 * ACPI 2.0 chapter 13 PCI interface definitions.
 */

#define AMD_EC_DATA	0x00	/* data register */
#define AMD_EC_SC	0x04	/* status of controller */
#define AMD_EC_CMD	0x04	/* command register */
#define AMD_EC_ICR	0x08	/* interrupt control register */

#define AMD_EC_SC_SMI	0x04	/* smi event pending */
#define AMD_EC_SC_SCI	0x02	/* sci event pending */
#define AMD_EC_SC_BURST	0x01	/* burst mode enabled */
#define AMD_EC_SC_CMD	0x08	/* byte in data reg is command */
#define AMD_EC_SC_IBF	0x02	/* data ready for embedded controller */
#define AMD_EC_SC_OBF	0x01	/* data ready for host */

#define AMD_EC_CMD_RD	0x80	/* read EC */
#define AMD_EC_CMD_WR	0x81	/* write EC */
#define AMD_EC_CMD_BE	0x82	/* enable burst mode */
#define AMD_EC_CMD_BD	0x83	/* disable burst mode */
#define AMD_EC_CMD_QR	0x84	/* query EC */

/*
 * ACPI 2.0 chapter 13 access of registers of the EC
 */

static int amd_ec_wait_write(struct amd_smbus *smbus)
{
	int timeout = 500;

	while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout)
		udelay(1);

	if (!timeout) {
		dev_warn(&smbus->dev->dev,
			 "Timeout while waiting for IBF to clear\n");
		return -ETIMEDOUT;
	}

	return 0;
}

static int amd_ec_wait_read(struct amd_smbus *smbus)
{
	int timeout = 500;

	while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout)
		udelay(1);

	if (!timeout) {
		dev_warn(&smbus->dev->dev,
			 "Timeout while waiting for OBF to set\n");
		return -ETIMEDOUT;
	}

	return 0;
}

static int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
		unsigned char *data)
{
	int status;

	status = amd_ec_wait_write(smbus);
	if (status)
		return status;
	outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD);

	status = amd_ec_wait_write(smbus);
	if (status)
		return status;
	outb(address, smbus->base + AMD_EC_DATA);

	status = amd_ec_wait_read(smbus);
	if (status)
		return status;
	*data = inb(smbus->base + AMD_EC_DATA);

Annotation

Implementation Notes