drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c
Extension
.c
Size
9872 bytes
Lines
384
Domain
Driver Families
Bucket
drivers/gpu
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret) {
			DRM_ERROR("Failed to register bit i2c %s\n", name);
			goto out_free;
		}
	}

	return i2c;
out_free:
	kfree(i2c);
	return NULL;

}

void amdgpu_i2c_init(struct amdgpu_device *adev)
{
	if (!adev->is_atom_fw) {
		if (!amdgpu_device_has_dc_support(adev)) {
			amdgpu_atombios_i2c_init(adev);
		} else {
			switch (adev->asic_type) {
			case CHIP_POLARIS10:
			case CHIP_POLARIS11:
			case CHIP_POLARIS12:
				amdgpu_atombios_oem_i2c_init(adev, 0x97);
				break;
			default:
				break;
			}
		}
	}
}

/* remove all the buses */
void amdgpu_i2c_fini(struct amdgpu_device *adev)
{
	int i;

	for (i = 0; i < AMDGPU_MAX_I2C_BUS; i++)
		if (adev->i2c_bus[i])
			adev->i2c_bus[i] = NULL;
}

/* looks up bus based on id */
struct amdgpu_i2c_chan *
amdgpu_i2c_lookup(struct amdgpu_device *adev,
		  const struct amdgpu_i2c_bus_rec *i2c_bus)
{
	int i;

	for (i = 0; i < AMDGPU_MAX_I2C_BUS; i++) {
		if (adev->i2c_bus[i] &&
		    (adev->i2c_bus[i]->rec.i2c_id == i2c_bus->i2c_id)) {
			return adev->i2c_bus[i];
		}
	}
	return NULL;
}

static int amdgpu_i2c_get_byte(struct amdgpu_i2c_chan *i2c_bus,
				 u8 slave_addr,
				 u8 addr,
				 u8 *val)
{
	u8 out_buf[2];
	u8 in_buf[2];
	struct i2c_msg msgs[] = {
		{
			.addr = slave_addr,
			.flags = 0,
			.len = 1,
			.buf = out_buf,
		},
		{
			.addr = slave_addr,
			.flags = I2C_M_RD,
			.len = 1,
			.buf = in_buf,
		}
	};

	out_buf[0] = addr;
	out_buf[1] = 0;

	if (i2c_transfer(&i2c_bus->adapter, msgs, 2) != 2) {
		DRM_DEBUG("i2c 0x%02x read failed\n", addr);
		return -EIO;
	}

	*val = in_buf[0];
	DRM_DEBUG("val = 0x%02x\n", *val);

Annotation

Implementation Notes