drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c

Source file repositories/reference/linux-study-clean/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
Extension
.c
Size
4539 bytes
Lines
196
Domain
Driver Families
Bucket
drivers/iio
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

else if (sub_elem->type == ACPI_TYPE_INTEGER) {
				if (sub_elem->integer.value != client->addr) {
					info->addr = sub_elem->integer.value;
					break; /* Not a MPU6500 primary */
				}
			}
		}
	}
	ret = cpm->package.count;
	kfree(buffer.pointer);

	return ret;
}

static int acpi_i2c_check_resource(struct acpi_resource *ares, void *data)
{
	struct acpi_resource_i2c_serialbus *sb;
	u32 *addr = data;

	if (i2c_acpi_get_i2c_resource(ares, &sb)) {
		if (*addr)
			*addr |= (sb->slave_address << 16);
		else
			*addr = sb->slave_address;
	}

	/* Tell the ACPI core that we already copied this address */
	return 1;
}

static int inv_mpu_process_acpi_config(struct i2c_client *client,
				       unsigned short *primary_addr,
				       unsigned short *secondary_addr)
{
	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
	u32 i2c_addr = 0;
	LIST_HEAD(resources);
	int ret;

	if (!is_acpi_device_node(dev_fwnode(&client->dev)))
		return -ENODEV;

	ret = acpi_dev_get_resources(adev, &resources,
				     acpi_i2c_check_resource, &i2c_addr);
	if (ret < 0)
		return ret;

	acpi_dev_free_resource_list(&resources);
	*primary_addr = lower_16_bits(i2c_addr);
	*secondary_addr = upper_16_bits(i2c_addr);

	return 0;
}

int inv_mpu_acpi_create_mux_client(struct i2c_client *client)
{
	struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev));
	struct acpi_device *adev = ACPI_COMPANION(&client->dev);

	st->mux_client = NULL;
	if (adev) {
		struct i2c_board_info info = { };
		struct i2c_client *mux_client;
		int ret = -1;

		dmi_check_system(inv_mpu_dev_list);
		switch (matched_product_name) {
		case INV_MPU_ASUS_T100TA:
			ret = asus_acpi_get_sensor_info(adev, client,
							&info);
			break;
		/* Add more matched product processing here */
		default:
			break;
		}

		if (ret < 0) {
			/* No matching DMI, so create device on INV6XX type */
			unsigned short primary, secondary;

			ret = inv_mpu_process_acpi_config(client, &primary,
							  &secondary);
			if (!ret && secondary) {
				char *name;

				info.addr = secondary;
				strscpy(info.type, dev_name(&adev->dev),
					sizeof(info.type));
				name = strchr(info.type, ':');
				if (name)

Annotation

Implementation Notes