drivers/iio/accel/bmc150-accel-i2c.c
Source file repositories/reference/linux-study-clean/drivers/iio/accel/bmc150-accel-i2c.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/accel/bmc150-accel-i2c.c- Extension
.c- Size
- 8818 bytes
- Lines
- 295
- 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.
- 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 or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/device.hlinux/mod_devicetable.hlinux/i2c.hlinux/module.hlinux/acpi.hlinux/regmap.hbmc150-accel.h
Detected Declarations
struct dual250e_set_angle_argsfunction bmc150_acpi_set_angle_dsmfunction bmc150_acpi_enable_keyboardfunction bmc150_acpi_resume_workfunction bmc150_acpi_resume_handlerfunction bmc150_acpi_dual_accel_probefunction bmc150_acpi_dual_accel_removefunction bmc150_acpi_dual_accel_probefunction bmc150_accel_remove
Annotated Snippet
struct dual250e_set_angle_args {
u32 aux0;
u32 ang0;
u32 rawx;
u32 rawy;
u32 rawz;
} __packed;
static bool bmc150_acpi_set_angle_dsm(struct i2c_client *client, u32 aux0, u32 ang0)
{
struct acpi_device *adev = ACPI_COMPANION(&client->dev);
struct dual250e_set_angle_args args = {
.aux0 = aux0,
.ang0 = ang0,
};
union acpi_object args_obj, *obj;
guid_t guid;
if (!acpi_dev_hid_uid_match(adev, "DUAL250E", NULL))
return false;
guid_parse(BMC150_DSM_GUID, &guid);
if (!acpi_check_dsm(adev->handle, &guid, 0, BIT(DUAL250E_SET_ANGLE_FN_INDEX)))
return false;
/*
* Note this triggers the following warning:
* "ACPI Warning: \_SB.PCI0.I2C2.ACC1._DSM: Argument #4 type mismatch -
* Found [Buffer], ACPI requires [Package]"
* This is unavoidable since the _DSM implementation expects a "naked"
* buffer, so wrapping it in a package will _not_ work.
*/
args_obj.type = ACPI_TYPE_BUFFER;
args_obj.buffer.length = sizeof(args);
args_obj.buffer.pointer = (u8 *)&args;
obj = acpi_evaluate_dsm(adev->handle, &guid, 0, DUAL250E_SET_ANGLE_FN_INDEX, &args_obj);
if (!obj) {
dev_err(&client->dev, "Failed to call DSM to enable keyboard and touchpad\n");
return false;
}
ACPI_FREE(obj);
return true;
}
static bool bmc150_acpi_enable_keyboard(struct i2c_client *client)
{
/*
* The EC must see a change for it to re-enable the kbd, so first
* set the angle to 270° (tent/stand mode) and then change it to
* 90° (laptop mode).
*/
if (!bmc150_acpi_set_angle_dsm(client, 0, 270))
return false;
/* The EC needs some time to notice the angle being changed */
msleep(100);
return bmc150_acpi_set_angle_dsm(client, 0, 90);
}
static void bmc150_acpi_resume_work(struct work_struct *work)
{
struct bmc150_accel_data *data =
container_of(work, struct bmc150_accel_data, resume_work.work);
bmc150_acpi_enable_keyboard(data->second_device);
}
static void bmc150_acpi_resume_handler(struct device *dev)
{
struct bmc150_accel_data *data = iio_priv(dev_get_drvdata(dev));
/*
* Delay the bmc150_acpi_enable_keyboard() call till after the system
* resume has completed, otherwise it will not work.
*/
schedule_delayed_work(&data->resume_work, msecs_to_jiffies(1000));
}
/*
* Some acpi_devices describe 2 accelerometers in a single ACPI device,
* try instantiating a second i2c_client for an I2cSerialBusV2 ACPI resource
* with index 1.
*/
static void bmc150_acpi_dual_accel_probe(struct i2c_client *client)
{
struct bmc150_accel_data *data = iio_priv(i2c_get_clientdata(client));
Annotation
- Immediate include surface: `linux/device.h`, `linux/mod_devicetable.h`, `linux/i2c.h`, `linux/module.h`, `linux/acpi.h`, `linux/regmap.h`, `bmc150-accel.h`.
- Detected declarations: `struct dual250e_set_angle_args`, `function bmc150_acpi_set_angle_dsm`, `function bmc150_acpi_enable_keyboard`, `function bmc150_acpi_resume_work`, `function bmc150_acpi_resume_handler`, `function bmc150_acpi_dual_accel_probe`, `function bmc150_acpi_dual_accel_remove`, `function bmc150_acpi_dual_accel_probe`, `function bmc150_accel_remove`.
- Atlas domain: Driver Families / drivers/iio.
- Implementation status: source 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.