/* Special LED class that can defer work */ struct delayed_led_classdev { struct led_classdev led_classdev; struct work_struct work; enum led_brightness new_brightness;
/* e0 25, e0 26, e0 27, e0 28 are scan codes that the accelerometer with acpi id
* HPQ6000 sends through the keyboard bus */ #define ACCEL_1 0x25 #define ACCEL_2 0x26 #define ACCEL_3 0x27 #define ACCEL_4 0x28
/* For automatic insertion of the module */ staticconststruct acpi_device_id lis3lv02d_device_ids[] = {
{"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */
{"HPQ6000", 0}, /* HP Mobile Data Protection System PNP */
{"HPQ6007", 0}, /* HP Mobile Data Protection System PNP */
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids);
/** * lis3lv02d_acpi_init - initialize the device for ACPI * @lis3: pointer to the device struct * * Returns 0 on success.
*/ staticint lis3lv02d_acpi_init(struct lis3lv02d *lis3)
{ return 0;
}
/** * lis3lv02d_acpi_read - ACPI ALRD method: read a register * @lis3: pointer to the device struct * @reg: the register to read * @ret: result of the operation * * Returns 0 on success.
*/ staticint lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret)
{ struct acpi_device *dev = lis3->bus_priv; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; unsignedlonglong lret;
acpi_status status;
arg0.integer.value = reg;
status = acpi_evaluate_integer(dev->handle, "ALRD", &args, &lret); if (ACPI_FAILURE(status)) return -EINVAL;
*ret = lret; return 0;
}
/** * lis3lv02d_acpi_write - ACPI ALWR method: write to a register * @lis3: pointer to the device struct * @reg: the register to write to * @val: the value to write * * Returns 0 on success.
*/ staticint lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val)
{ struct acpi_device *dev = lis3->bus_priv; unsignedlonglong ret; /* Not used when writting */ union acpi_object in_obj[2]; struct acpi_object_list args = { 2, in_obj };
/* obtain IRQ number of our device from ACPI */
ret = platform_get_irq_optional(device, 0); if (ret > 0)
lis3_dev.irq = ret;
/* If possible use a "standard" axes order */ if (lis3_dev.ac.x && lis3_dev.ac.y && lis3_dev.ac.z) {
pr_info("Using custom axes %d,%d,%d\n",
lis3_dev.ac.x, lis3_dev.ac.y, lis3_dev.ac.z);
} elseif (dmi_check_system(lis3lv02d_dmi_ids) == 0) {
pr_info("laptop model unknown, using default axes configuration\n");
lis3_dev.ac = lis3lv02d_axis_normal;
}
/* call the core layer do its init */
ret = lis3lv02d_init_device(&lis3_dev); if (ret) return ret;
/* filter to remove HPQ6000 accelerometer data
* from keyboard bus stream */ if (strstr(dev_name(&device->dev), "HPQ6000"))
i8042_install_filter(hp_accel_i8042_filter, NULL);
INIT_WORK(&hpled_led.work, delayed_set_status_worker);
ret = led_classdev_register(NULL, &hpled_led.led_classdev); if (ret) {
i8042_remove_filter(hp_accel_i8042_filter);
lis3lv02d_joystick_disable(&lis3_dev);
lis3lv02d_poweroff(&lis3_dev);
flush_work(&hpled_led.work);
lis3lv02d_remove_fs(&lis3_dev); return ret;
}
staticint __maybe_unused lis3lv02d_suspend(struct device *dev)
{ /* make sure the device is off when we suspend */
lis3lv02d_poweroff(&lis3_dev); return 0;
}
/* For the HP MDPS aka 3D Driveguard */ staticstruct platform_driver lis3lv02d_driver = {
.probe = lis3lv02d_probe,
.remove = lis3lv02d_remove,
.driver = {
.name = "hp_accel",
.pm = &hp_accel_pm,
.acpi_match_table = lis3lv02d_device_ids,
},
};
module_platform_driver(lis3lv02d_driver);
MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED.");
MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
MODULE_LICENSE("GPL");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.