From 9c78ff6e65cad9f9fcf0bbde2bfbbf3a544fb704 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 20 Oct 2008 23:02:43 +0100 Subject: leds: Add driver for HP harddisk protection LEDs HP notebooks contain accelerometer-based disk protection subsystem, and LED that indicates hard disk is protected. This is driver for the LED part. Signed-off-by: Pavel Machek Signed-off-by: Richard Purdie --- drivers/leds/leds-hp-disk.c | 156 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 drivers/leds/leds-hp-disk.c (limited to 'drivers/leds/leds-hp-disk.c') diff --git a/drivers/leds/leds-hp-disk.c b/drivers/leds/leds-hp-disk.c new file mode 100644 index 00000000000..d636280198a --- /dev/null +++ b/drivers/leds/leds-hp-disk.c @@ -0,0 +1,156 @@ +/* + * leds-hp-disk.c - driver for HP "hard disk protection" LED + * + * Copyright (C) 2008 Pavel Machek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "leds-hp-disk" +#define ACPI_MDPS_CLASS "led" + +/* For automatic insertion of the module */ +static struct acpi_device_id hpled_device_ids[] = { + {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, hpled_device_ids); + +struct acpi_hpled { + struct acpi_device *device; /* The ACPI device */ +}; + +static struct acpi_hpled adev; + +static acpi_status hpled_acpi_write(acpi_handle handle, int reg) +{ + unsigned long ret; /* Not used when writing */ + union acpi_object in_obj[1]; + struct acpi_object_list args = { 1, in_obj }; + + in_obj[0].type = ACPI_TYPE_INTEGER; + in_obj[0].integer.value = reg; + + return acpi_evaluate_integer(handle, "ALED", &args, &ret); +} + +static void hpled_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + hpled_acpi_write(adev.device->handle, !!value); +} + +static struct led_classdev hpled_led = { + .name = "hp:red:hddprotection", + .default_trigger = "heartbeat", + .brightness_set = hpled_set, +}; + +#ifdef CONFIG_PM +static int hpled_suspend(struct acpi_device *dev, pm_message_t state) +{ + led_classdev_suspend(&hpled_led); + return 0; +} + +static int hpled_resume(struct acpi_device *dev) +{ + led_classdev_resume(&hpled_led); + return 0; +} +#else +#define hpled_suspend NULL +#define hpled_resume NULL +#endif + +static int hpled_add(struct acpi_device *device) +{ + int ret; + + if (!device) + return -EINVAL; + + adev.device = device; + strcpy(acpi_device_name(device), DRIVER_NAME); + strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); + acpi_driver_data(device) = &adev; + + ret = led_classdev_register(NULL, &hpled_led); + return ret; +} + +static int hpled_remove(struct acpi_device *device, int type) +{ + if (!device) + return -EINVAL; + + led_classdev_unregister(&hpled_led); + return 0; +} + + + +static struct acpi_driver leds_hp_driver = { + .name = DRIVER_NAME, + .class = ACPI_MDPS_CLASS, + .ids = hpled_device_ids, + .ops = { + .add = hpled_add, + .remove = hpled_remove, + .suspend = hpled_suspend, + .resume = hpled_resume, + } +}; + +static int __init hpled_init_module(void) +{ + int ret; + + if (acpi_disabled) + return -ENODEV; + + ret = acpi_bus_register_driver(&leds_hp_driver); + if (ret < 0) + return ret; + + printk(KERN_INFO DRIVER_NAME " driver loaded.\n"); + + return 0; +} + +static void __exit hpled_exit_module(void) +{ + acpi_bus_unregister_driver(&leds_hp_driver); +} + +MODULE_DESCRIPTION("Driver for HP disk protection LED"); +MODULE_AUTHOR("Pavel Machek "); +MODULE_LICENSE("GPL"); + +module_init(hpled_init_module); +module_exit(hpled_exit_module); -- cgit v1.2.3 From 601a1b92ed3ce0025f7bec6fc591cceaef8d9d69 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 23 Oct 2008 22:35:19 +0100 Subject: leds/acpi: Fix merge fallout from acpi_driver_data change Signed-off-by: Stephen Rothwell Signed-off-by: Richard Purdie --- drivers/leds/leds-hp-disk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/leds/leds-hp-disk.c') diff --git a/drivers/leds/leds-hp-disk.c b/drivers/leds/leds-hp-disk.c index d636280198a..53a25b1c2da 100644 --- a/drivers/leds/leds-hp-disk.c +++ b/drivers/leds/leds-hp-disk.c @@ -98,7 +98,7 @@ static int hpled_add(struct acpi_device *device) adev.device = device; strcpy(acpi_device_name(device), DRIVER_NAME); strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); - acpi_driver_data(device) = &adev; + device->driver_data = &adev; ret = led_classdev_register(NULL, &hpled_led); return ret; -- cgit v1.2.3