2019-05-27 08:55:05 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2009-01-09 16:41:01 -08:00
/*
* hp_accel . c - Interface between LIS3LV02DL driver and HP ACPI BIOS
*
* Copyright ( C ) 2007 - 2008 Yan Burman
* Copyright ( C ) 2008 Eric Piel
2009-01-15 13:51:24 -08:00
* Copyright ( C ) 2008 - 2009 Pavel Machek
2009-01-09 16:41:01 -08:00
*/
2010-10-20 06:51:35 +00:00
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2009-01-09 16:41:01 -08:00
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/dmi.h>
# include <linux/module.h>
# include <linux/types.h>
# include <linux/platform_device.h>
# include <linux/interrupt.h>
# include <linux/delay.h>
# include <linux/wait.h>
# include <linux/poll.h>
# include <linux/freezer.h>
# include <linux/uaccess.h>
2009-01-15 13:51:23 -08:00
# include <linux/leds.h>
2011-03-21 17:59:36 +01:00
# include <linux/atomic.h>
2013-12-03 08:49:16 +08:00
# include <linux/acpi.h>
2014-10-30 18:57:47 +02:00
# include <linux/i8042.h>
# include <linux/serio.h>
2011-03-21 17:59:36 +01:00
# include "../../misc/lis3lv02d/lis3lv02d.h"
2009-01-09 16:41:01 -08:00
2009-01-15 13:51:24 -08:00
/* Delayed LEDs infrastructure ------------------------------------ */
/* 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 ;
unsigned int led ; /* For driver */
void ( * set_brightness ) ( struct delayed_led_classdev * data , enum led_brightness value ) ;
} ;
static inline void delayed_set_status_worker ( struct work_struct * work )
{
struct delayed_led_classdev * data =
container_of ( work , struct delayed_led_classdev , work ) ;
data - > set_brightness ( data , data - > new_brightness ) ;
}
static inline void delayed_sysfs_set ( struct led_classdev * led_cdev ,
enum led_brightness brightness )
{
struct delayed_led_classdev * data = container_of ( led_cdev ,
struct delayed_led_classdev , led_classdev ) ;
data - > new_brightness = brightness ;
schedule_work ( & data - > work ) ;
}
/* HP-specific accelerometer driver ------------------------------------ */
2009-01-09 16:41:01 -08:00
2014-10-30 18:57:47 +02:00
/* 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
2009-01-09 16:41:01 -08:00
/* For automatic insertion of the module */
2014-07-16 19:43:14 +02:00
static const struct acpi_device_id lis3lv02d_device_ids [ ] = {
2009-01-09 16:41:01 -08:00
{ " HPQ0004 " , 0 } , /* HP Mobile Data Protection System PNP */
2011-09-15 12:24:47 +02:00
{ " HPQ6000 " , 0 } , /* HP Mobile Data Protection System PNP */
2014-01-13 12:32:44 +01:00
{ " HPQ6007 " , 0 } , /* HP Mobile Data Protection System PNP */
2009-01-09 16:41:01 -08:00
{ " " , 0 } ,
} ;
MODULE_DEVICE_TABLE ( acpi , lis3lv02d_device_ids ) ;
/**
2021-08-23 12:32:21 +03:00
* lis3lv02d_acpi_init - initialize the device for ACPI
2009-03-31 15:24:32 -07:00
* @ lis3 : pointer to the device struct
2009-01-09 16:41:01 -08:00
*
2009-03-31 15:24:32 -07:00
* Returns 0 on success .
2009-01-09 16:41:01 -08:00
*/
2013-12-13 12:56:34 +05:30
static int lis3lv02d_acpi_init ( struct lis3lv02d * lis3 )
2009-01-09 16:41:01 -08:00
{
2009-03-31 15:24:32 -07:00
return 0 ;
2009-01-09 16:41:01 -08:00
}
/**
* lis3lv02d_acpi_read - ACPI ALRD method : read a register
2009-03-31 15:24:32 -07:00
* @ lis3 : pointer to the device struct
2009-01-09 16:41:01 -08:00
* @ reg : the register to read
* @ ret : result of the operation
*
2009-03-31 15:24:32 -07:00
* Returns 0 on success .
2009-01-09 16:41:01 -08:00
*/
2013-12-13 12:56:34 +05:30
static int lis3lv02d_acpi_read ( struct lis3lv02d * lis3 , int reg , u8 * ret )
2009-01-09 16:41:01 -08:00
{
2009-03-31 15:24:32 -07:00
struct acpi_device * dev = lis3 - > bus_priv ;
2009-01-09 16:41:01 -08:00
union acpi_object arg0 = { ACPI_TYPE_INTEGER } ;
struct acpi_object_list args = { 1 , & arg0 } ;
unsigned long long lret ;
acpi_status status ;
arg0 . integer . value = reg ;
2009-03-31 15:24:32 -07:00
status = acpi_evaluate_integer ( dev - > handle , " ALRD " , & args , & lret ) ;
2016-04-15 17:47:20 +03:00
if ( ACPI_FAILURE ( status ) )
return - EINVAL ;
2009-01-09 16:41:01 -08:00
* ret = lret ;
2016-04-15 17:47:20 +03:00
return 0 ;
2009-01-09 16:41:01 -08:00
}
/**
* lis3lv02d_acpi_write - ACPI ALWR method : write to a register
2009-03-31 15:24:32 -07:00
* @ lis3 : pointer to the device struct
2009-01-09 16:41:01 -08:00
* @ reg : the register to write to
* @ val : the value to write
*
2009-03-31 15:24:32 -07:00
* Returns 0 on success .
2009-01-09 16:41:01 -08:00
*/
2013-12-13 12:56:34 +05:30
static int lis3lv02d_acpi_write ( struct lis3lv02d * lis3 , int reg , u8 val )
2009-01-09 16:41:01 -08:00
{
2009-03-31 15:24:32 -07:00
struct acpi_device * dev = lis3 - > bus_priv ;
2009-01-09 16:41:01 -08:00
unsigned long long ret ; /* Not used when writting */
union acpi_object in_obj [ 2 ] ;
struct acpi_object_list args = { 2 , in_obj } ;
in_obj [ 0 ] . type = ACPI_TYPE_INTEGER ;
in_obj [ 0 ] . integer . value = reg ;
in_obj [ 1 ] . type = ACPI_TYPE_INTEGER ;
in_obj [ 1 ] . integer . value = val ;
2009-03-31 15:24:32 -07:00
if ( acpi_evaluate_integer ( dev - > handle , " ALWR " , & args , & ret ) ! = AE_OK )
return - EINVAL ;
return 0 ;
2009-01-09 16:41:01 -08:00
}
static int lis3lv02d_dmi_matched ( const struct dmi_system_id * dmi )
{
2010-10-01 17:14:25 -04:00
lis3_dev . ac = * ( ( union axis_conversion * ) dmi - > driver_data ) ;
2010-10-20 06:51:35 +00:00
pr_info ( " hardware type %s found \n " , dmi - > ident ) ;
2009-01-09 16:41:01 -08:00
return 1 ;
}
/* Represents, for each axis seen by userspace, the corresponding hw axis (+1).
* If the value is negative , the opposite of the hw value is used . */
2010-10-01 17:14:25 -04:00
# define DEFINE_CONV(name, x, y, z) \
static union axis_conversion lis3lv02d_axis_ # # name = \
{ . as_array = { x , y , z } }
DEFINE_CONV ( normal , 1 , 2 , 3 ) ;
DEFINE_CONV ( y_inverted , 1 , - 2 , 3 ) ;
DEFINE_CONV ( x_inverted , - 1 , 2 , 3 ) ;
2016-04-02 20:11:13 +02:00
DEFINE_CONV ( x_inverted_usd , - 1 , 2 , - 3 ) ;
2010-10-01 17:14:25 -04:00
DEFINE_CONV ( z_inverted , 1 , 2 , - 3 ) ;
DEFINE_CONV ( xy_swap , 2 , 1 , 3 ) ;
DEFINE_CONV ( xy_rotated_left , - 2 , 1 , 3 ) ;
DEFINE_CONV ( xy_rotated_left_usd , - 2 , 1 , - 3 ) ;
DEFINE_CONV ( xy_swap_inverted , - 2 , - 1 , 3 ) ;
DEFINE_CONV ( xy_rotated_right , 2 , - 1 , 3 ) ;
DEFINE_CONV ( xy_swap_yz_inverted , 2 , - 1 , - 3 ) ;
2009-01-09 16:41:01 -08:00
# define AXIS_DMI_MATCH(_ident, _name, _axis) { \
. ident = _ident , \
. callback = lis3lv02d_dmi_matched , \
. matches = { \
DMI_MATCH ( DMI_PRODUCT_NAME , _name ) \
} , \
. driver_data = & lis3lv02d_axis_ # # _axis \
}
2009-02-18 14:48:25 -08:00
# define AXIS_DMI_MATCH2(_ident, _class1, _name1, \
_class2 , _name2 , \
_axis ) { \
. ident = _ident , \
. callback = lis3lv02d_dmi_matched , \
. matches = { \
DMI_MATCH ( DMI_ # # _class1 , _name1 ) , \
DMI_MATCH ( DMI_ # # _class2 , _name2 ) , \
} , \
. driver_data = & lis3lv02d_axis_ # # _axis \
}
2014-07-16 19:43:14 +02:00
static const struct dmi_system_id lis3lv02d_dmi_ids [ ] = {
2009-01-09 16:41:01 -08:00
/* product names are truncated to match all kinds of a same model */
AXIS_DMI_MATCH ( " NC64x0 " , " HP Compaq nc64 " , x_inverted ) ,
AXIS_DMI_MATCH ( " NC84x0 " , " HP Compaq nc84 " , z_inverted ) ,
AXIS_DMI_MATCH ( " NX9420 " , " HP Compaq nx9420 " , x_inverted ) ,
AXIS_DMI_MATCH ( " NW9440 " , " HP Compaq nw9440 " , x_inverted ) ,
AXIS_DMI_MATCH ( " NC2510 " , " HP Compaq 2510 " , y_inverted ) ,
2009-06-16 15:34:16 -07:00
AXIS_DMI_MATCH ( " NC2710 " , " HP Compaq 2710 " , xy_swap ) ,
2009-01-09 16:41:01 -08:00
AXIS_DMI_MATCH ( " NC8510 " , " HP Compaq 8510 " , xy_swap_inverted ) ,
AXIS_DMI_MATCH ( " HP2133 " , " HP 2133 " , xy_rotated_left ) ,
2009-03-31 15:24:29 -07:00
AXIS_DMI_MATCH ( " HP2140 " , " HP 2140 " , xy_swap_inverted ) ,
2009-02-04 15:12:11 -08:00
AXIS_DMI_MATCH ( " NC653x " , " HP Compaq 653 " , xy_rotated_left_usd ) ,
2009-10-26 16:50:19 -07:00
AXIS_DMI_MATCH ( " NC6730b " , " HP Compaq 6730b " , xy_rotated_left_usd ) ,
AXIS_DMI_MATCH ( " NC6730s " , " HP Compaq 6730s " , xy_swap ) ,
2009-02-04 15:12:09 -08:00
AXIS_DMI_MATCH ( " NC651xx " , " HP Compaq 651 " , xy_rotated_right ) ,
2009-06-16 15:34:16 -07:00
AXIS_DMI_MATCH ( " NC6710x " , " HP Compaq 6710 " , xy_swap_yz_inverted ) ,
AXIS_DMI_MATCH ( " NC6715x " , " HP Compaq 6715 " , y_inverted ) ,
AXIS_DMI_MATCH ( " NC693xx " , " HP EliteBook 693 " , xy_rotated_right ) ,
2009-10-26 16:50:20 -07:00
AXIS_DMI_MATCH ( " NC693xx " , " HP EliteBook 853 " , xy_swap ) ,
2011-10-31 17:10:46 -07:00
AXIS_DMI_MATCH ( " NC854xx " , " HP EliteBook 854 " , y_inverted ) ,
2011-10-31 17:10:43 -07:00
AXIS_DMI_MATCH ( " NC273xx " , " HP EliteBook 273 " , y_inverted ) ,
2009-02-18 14:48:25 -08:00
/* Intel-based HP Pavilion dv5 */
AXIS_DMI_MATCH2 ( " HPDV5_I " ,
PRODUCT_NAME , " HP Pavilion dv5 " ,
BOARD_NAME , " 3603 " ,
x_inverted ) ,
/* AMD-based HP Pavilion dv5 */
AXIS_DMI_MATCH2 ( " HPDV5_A " ,
PRODUCT_NAME , " HP Pavilion dv5 " ,
BOARD_NAME , " 3600 " ,
y_inverted ) ,
2009-03-31 15:24:29 -07:00
AXIS_DMI_MATCH ( " DV7 " , " HP Pavilion dv7 " , x_inverted ) ,
hp_accel: axis conversion for hp compaq 8710w
I have a laptop HP Compaq 8710W, I compiled into my kernel the LIS3LV02DL
and HP_ACCEL module drivers. While loading it cannot recognize the laptop
model, so i am sending the necessary information to update the database of
axis orientations.
>When the laptop is horizontal the position reported is about 0 for X and Y
>and a positive value for Z
Yes, it is about 0,0,1000, the actual reading says: (-17,-26,1018);
> If the left side is elevated, X increases (becomes positive)
Yes, X goes toward to positive 1000.
>If the front side (where the touchpad is) is elevated, Y decreases (becomes negative)
No, Y goes toward to positive 1000.
>If the laptop is put upside-down, Z becomes negative
Yes, the laptop on a table Z gives 1000, and if upsidedown the Z reads
-1000.
So in few words the Y axis is inverted.
Cc: Eric Piel <eric.piel@tremplin-utc.net>
Signed-off-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-03-31 15:24:31 -07:00
AXIS_DMI_MATCH ( " HP8710 " , " HP Compaq 8710 " , y_inverted ) ,
2009-10-26 16:50:21 -07:00
AXIS_DMI_MATCH ( " HDX18 " , " HP HDX 18 " , x_inverted ) ,
2010-04-23 13:17:48 -04:00
AXIS_DMI_MATCH ( " HPB432x " , " HP ProBook 432 " , xy_rotated_left ) ,
2016-04-02 20:11:13 +02:00
AXIS_DMI_MATCH ( " HPB440G3 " , " HP ProBook 440 G3 " , x_inverted_usd ) ,
2017-10-21 10:42:21 +00:00
AXIS_DMI_MATCH ( " HPB440G4 " , " HP ProBook 440 G4 " , x_inverted ) ,
2010-04-23 13:17:48 -04:00
AXIS_DMI_MATCH ( " HPB442x " , " HP ProBook 442 " , xy_rotated_left ) ,
2019-06-03 13:14:46 +02:00
AXIS_DMI_MATCH ( " HPB450G0 " , " HP ProBook 450 G0 " , x_inverted ) ,
2010-04-23 13:17:48 -04:00
AXIS_DMI_MATCH ( " HPB452x " , " HP ProBook 452 " , y_inverted ) ,
AXIS_DMI_MATCH ( " HPB522x " , " HP ProBook 522 " , xy_swap ) ,
2010-09-09 16:37:31 -07:00
AXIS_DMI_MATCH ( " HPB532x " , " HP ProBook 532 " , y_inverted ) ,
2011-10-31 17:10:50 -07:00
AXIS_DMI_MATCH ( " HPB655x " , " HP ProBook 655 " , xy_swap_inverted ) ,
2010-08-27 00:21:43 +00:00
AXIS_DMI_MATCH ( " Mini510x " , " HP Mini 510 " , xy_rotated_left_usd ) ,
2011-09-15 12:29:26 +02:00
AXIS_DMI_MATCH ( " HPB63xx " , " HP ProBook 63 " , xy_swap ) ,
AXIS_DMI_MATCH ( " HPB64xx " , " HP ProBook 64 " , xy_swap ) ,
AXIS_DMI_MATCH ( " HPB64xx " , " HP EliteBook 84 " , xy_swap ) ,
AXIS_DMI_MATCH ( " HPB65xx " , " HP ProBook 65 " , x_inverted ) ,
2014-11-13 20:57:37 +01:00
AXIS_DMI_MATCH ( " HPZBook15 " , " HP ZBook 15 " , x_inverted ) ,
2019-07-10 13:33:26 +08:00
AXIS_DMI_MATCH ( " HPZBook17G5 " , " HP ZBook 17 G5 " , x_inverted ) ,
2016-12-21 10:55:53 +01:00
AXIS_DMI_MATCH ( " HPZBook17 " , " HP ZBook 17 " , xy_swap_yz_inverted ) ,
2009-01-09 16:41:01 -08:00
{ NULL , }
/* Laptop models without axis info (yet):
* " NC6910 " " HP Compaq 6910 "
* " NC2400 " " HP Compaq nc2400 "
* " NX74x0 " " HP Compaq nx74 "
* " NX6325 " " HP Compaq nx6325 "
* " NC4400 " " HP Compaq nc4400 "
*/
} ;
2009-01-15 13:51:24 -08:00
static void hpled_set ( struct delayed_led_classdev * led_cdev , enum led_brightness value )
2009-01-15 13:51:23 -08:00
{
2009-03-31 15:24:32 -07:00
struct acpi_device * dev = lis3_dev . bus_priv ;
2009-01-15 13:51:23 -08:00
unsigned long 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 ;
2009-01-15 13:51:24 -08:00
in_obj [ 0 ] . integer . value = ! ! value ;
2009-01-15 13:51:23 -08:00
2009-03-31 15:24:32 -07:00
acpi_evaluate_integer ( dev - > handle , " ALED " , & args , & ret ) ;
2009-01-15 13:51:23 -08:00
}
2009-01-15 13:51:24 -08:00
static struct delayed_led_classdev hpled_led = {
. led_classdev = {
. name = " hp::hddprotect " ,
. default_trigger = " none " ,
. brightness_set = delayed_sysfs_set ,
. flags = LED_CORE_SUSPENDRESUME ,
} ,
. set_brightness = hpled_set ,
2009-01-15 13:51:23 -08:00
} ;
2009-01-09 16:41:01 -08:00
2014-10-30 18:57:47 +02:00
static bool hp_accel_i8042_filter ( unsigned char data , unsigned char str ,
struct serio * port )
{
static bool extended ;
if ( str & I8042_STR_AUXDATA )
return false ;
if ( data = = 0xe0 ) {
extended = true ;
return true ;
} else if ( unlikely ( extended ) ) {
extended = false ;
switch ( data ) {
case ACCEL_1 :
case ACCEL_2 :
case ACCEL_3 :
case ACCEL_4 :
return true ;
default :
serio_interrupt ( port , 0xe0 , 0 ) ;
return false ;
}
}
return false ;
}
2021-08-23 12:32:22 +03:00
static int lis3lv02d_probe ( struct platform_device * device )
2009-01-09 16:41:01 -08:00
{
2009-01-15 13:51:23 -08:00
int ret ;
2009-01-09 16:41:01 -08:00
2021-08-23 12:32:22 +03:00
lis3_dev . bus_priv = ACPI_COMPANION ( & device - > dev ) ;
2009-03-31 15:24:26 -07:00
lis3_dev . init = lis3lv02d_acpi_init ;
lis3_dev . read = lis3lv02d_acpi_read ;
lis3_dev . write = lis3lv02d_acpi_write ;
2009-01-09 16:41:01 -08:00
2009-03-31 15:24:32 -07:00
/* obtain IRQ number of our device from ACPI */
2021-08-23 12:32:22 +03:00
ret = platform_get_irq_optional ( device , 0 ) ;
if ( ret > 0 )
lis3_dev . irq = ret ;
2009-01-09 16:41:01 -08:00
/* If possible use a "standard" axes order */
2010-10-01 17:14:25 -04:00
if ( lis3_dev . ac . x & & lis3_dev . ac . y & & lis3_dev . ac . z ) {
2010-10-20 06:51:35 +00:00
pr_info ( " Using custom axes %d,%d,%d \n " ,
lis3_dev . ac . x , lis3_dev . ac . y , lis3_dev . ac . z ) ;
2010-10-01 17:14:25 -04:00
} else if ( dmi_check_system ( lis3lv02d_dmi_ids ) = = 0 ) {
2010-10-20 06:51:35 +00:00
pr_info ( " laptop model unknown, using default axes configuration \n " ) ;
2009-03-31 15:24:26 -07:00
lis3_dev . ac = lis3lv02d_axis_normal ;
2009-01-09 16:41:01 -08:00
}
2009-03-31 15:24:32 -07:00
/* call the core layer do its init */
ret = lis3lv02d_init_device ( & lis3_dev ) ;
2009-01-15 13:51:23 -08:00
if ( ret )
return ret ;
2014-10-30 18:57:47 +02:00
/* filter to remove HPQ6000 accelerometer data
* from keyboard bus stream */
if ( strstr ( dev_name ( & device - > dev ) , " HPQ6000 " ) )
i8042_install_filter ( hp_accel_i8042_filter ) ;
2009-03-31 15:24:32 -07:00
INIT_WORK ( & hpled_led . work , delayed_set_status_worker ) ;
ret = led_classdev_register ( NULL , & hpled_led . led_classdev ) ;
2009-01-15 13:51:23 -08:00
if ( ret ) {
2021-11-07 20:57:07 +01:00
i8042_remove_filter ( hp_accel_i8042_filter ) ;
2011-10-31 17:11:02 -07:00
lis3lv02d_joystick_disable ( & lis3_dev ) ;
2009-03-31 15:24:32 -07:00
lis3lv02d_poweroff ( & lis3_dev ) ;
2009-01-15 13:51:24 -08:00
flush_work ( & hpled_led . work ) ;
2021-11-07 20:57:07 +01:00
lis3lv02d_remove_fs ( & lis3_dev ) ;
2009-01-15 13:51:23 -08:00
return ret ;
}
return ret ;
2009-01-09 16:41:01 -08:00
}
2021-08-23 12:32:22 +03:00
static int lis3lv02d_remove ( struct platform_device * device )
2009-01-09 16:41:01 -08:00
{
2014-10-30 18:57:47 +02:00
i8042_remove_filter ( hp_accel_i8042_filter ) ;
2011-10-31 17:11:02 -07:00
lis3lv02d_joystick_disable ( & lis3_dev ) ;
2009-03-31 15:24:32 -07:00
lis3lv02d_poweroff ( & lis3_dev ) ;
2009-01-09 16:41:01 -08:00
2009-01-15 13:51:24 -08:00
led_classdev_unregister ( & hpled_led . led_classdev ) ;
2010-05-11 14:07:03 -07:00
flush_work ( & hpled_led . work ) ;
2009-01-15 13:51:23 -08:00
2021-10-12 17:39:37 +02:00
lis3lv02d_remove_fs ( & lis3_dev ) ;
return 0 ;
2009-01-09 16:41:01 -08:00
}
2021-12-06 17:15:21 +02:00
static int __maybe_unused lis3lv02d_suspend ( struct device * dev )
2009-01-09 16:41:01 -08:00
{
/* make sure the device is off when we suspend */
2009-03-31 15:24:32 -07:00
lis3lv02d_poweroff ( & lis3_dev ) ;
2009-01-09 16:41:01 -08:00
return 0 ;
}
2021-12-06 17:15:21 +02:00
static int __maybe_unused lis3lv02d_resume ( struct device * dev )
2009-01-09 16:41:01 -08:00
{
2021-04-30 14:07:35 +08:00
lis3lv02d_poweron ( & lis3_dev ) ;
return 0 ;
}
2021-12-06 17:15:21 +02:00
static SIMPLE_DEV_PM_OPS ( hp_accel_pm , lis3lv02d_suspend , lis3lv02d_resume ) ;
2009-01-09 16:41:01 -08:00
/* For the HP MDPS aka 3D Driveguard */
2021-08-23 12:32:22 +03:00
static struct platform_driver lis3lv02d_driver = {
. probe = lis3lv02d_probe ,
. remove = lis3lv02d_remove ,
. driver = {
. name = " hp_accel " ,
2021-12-06 17:15:21 +02:00
. pm = & hp_accel_pm ,
2021-08-23 12:32:22 +03:00
. acpi_match_table = lis3lv02d_device_ids ,
2012-06-27 23:27:25 +02:00
} ,
2009-01-09 16:41:01 -08:00
} ;
2021-08-23 12:32:22 +03:00
module_platform_driver ( lis3lv02d_driver ) ;
2009-01-09 16:41:01 -08:00
2009-01-15 13:51:23 -08:00
MODULE_DESCRIPTION ( " Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED. " ) ;
2009-01-09 16:41:01 -08:00
MODULE_AUTHOR ( " Yan Burman, Eric Piel, Pavel Machek " ) ;
MODULE_LICENSE ( " GPL " ) ;