From 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:44:59 +0000
Subject: [PATCH] gmac get mac form eeprom
---
kernel/drivers/input/mouse/elan_i2c_core.c | 419 ++++++++++++++++++++++++++++++-----------------------------
1 files changed, 211 insertions(+), 208 deletions(-)
diff --git a/kernel/drivers/input/mouse/elan_i2c_core.c b/kernel/drivers/input/mouse/elan_i2c_core.c
index ae01263..6f59c8b 100644
--- a/kernel/drivers/input/mouse/elan_i2c_core.c
+++ b/kernel/drivers/input/mouse/elan_i2c_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Elan I2C/SMBus Touchpad driver
*
@@ -10,10 +11,6 @@
* Based on cyapa driver:
* copyright (c) 2011-2012 Cypress Semiconductor, Inc.
* copyright (c) 2011-2012 Google, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
*
* Trademarks are the property of their respective owners.
*/
@@ -37,6 +34,7 @@
#include <linux/completion.h>
#include <linux/of.h>
#include <linux/property.h>
+#include <linux/input/elan-i2c-ids.h>
#include <linux/regulator/consumer.h>
#include <asm/unaligned.h>
@@ -48,16 +46,6 @@
#define ETP_FWIDTH_REDUCE 90
#define ETP_FINGER_WIDTH 15
#define ETP_RETRY_COUNT 3
-
-#define ETP_MAX_FINGERS 5
-#define ETP_FINGER_DATA_LEN 5
-#define ETP_REPORT_ID 0x5D
-#define ETP_TP_REPORT_ID 0x5E
-#define ETP_REPORT_ID_OFFSET 2
-#define ETP_TOUCH_INFO_OFFSET 3
-#define ETP_FINGER_DATA_OFFSET 4
-#define ETP_HOVER_INFO_OFFSET 30
-#define ETP_MAX_REPORT_LEN 34
/* The main device structure */
struct elan_tp_data {
@@ -87,11 +75,14 @@
u8 sm_version;
u8 iap_version;
u16 fw_checksum;
+ unsigned int report_features;
+ unsigned int report_len;
int pressure_adjustment;
u8 mode;
u16 ic_type;
u16 fw_validpage_count;
- u16 fw_signature_address;
+ u16 fw_page_size;
+ u32 fw_signature_address;
bool irq_wake;
@@ -99,10 +90,11 @@
u8 max_baseline;
bool baseline_ready;
u8 clickpad;
+ bool middle_button;
};
-static int elan_get_fwinfo(u16 ic_type, u16 *validpage_count,
- u16 *signature_address)
+static int elan_get_fwinfo(u16 ic_type, u8 iap_version, u16 *validpage_count,
+ u32 *signature_address, u16 *page_size)
{
switch (ic_type) {
case 0x00:
@@ -127,68 +119,55 @@
case 0x10:
*validpage_count = 1024;
break;
+ case 0x11:
+ *validpage_count = 1280;
+ break;
+ case 0x13:
+ *validpage_count = 2048;
+ break;
+ case 0x14:
+ case 0x15:
+ *validpage_count = 1024;
+ break;
default:
/* unknown ic type clear value */
*validpage_count = 0;
*signature_address = 0;
+ *page_size = 0;
return -ENXIO;
}
*signature_address =
(*validpage_count * ETP_FW_PAGE_SIZE) - ETP_FW_SIGNATURE_SIZE;
+ if ((ic_type == 0x14 || ic_type == 0x15) && iap_version >= 2) {
+ *validpage_count /= 8;
+ *page_size = ETP_FW_PAGE_SIZE_512;
+ } else if (ic_type >= 0x0D && iap_version >= 1) {
+ *validpage_count /= 2;
+ *page_size = ETP_FW_PAGE_SIZE_128;
+ } else {
+ *page_size = ETP_FW_PAGE_SIZE;
+ }
+
return 0;
}
-static int elan_enable_power(struct elan_tp_data *data)
+static int elan_set_power(struct elan_tp_data *data, bool on)
{
int repeat = ETP_RETRY_COUNT;
int error;
- error = regulator_enable(data->vcc);
- if (error) {
- dev_err(&data->client->dev,
- "failed to enable regulator: %d\n", error);
- return error;
- }
-
do {
- error = data->ops->power_control(data->client, true);
+ error = data->ops->power_control(data->client, on);
if (error >= 0)
return 0;
msleep(30);
} while (--repeat > 0);
- dev_err(&data->client->dev, "failed to enable power: %d\n", error);
- return error;
-}
-
-static int elan_disable_power(struct elan_tp_data *data)
-{
- int repeat = ETP_RETRY_COUNT;
- int error;
-
- do {
- error = data->ops->power_control(data->client, false);
- if (!error) {
- error = regulator_disable(data->vcc);
- if (error) {
- dev_err(&data->client->dev,
- "failed to disable regulator: %d\n",
- error);
- /* Attempt to power the chip back up */
- data->ops->power_control(data->client, true);
- break;
- }
-
- return 0;
- }
-
- msleep(30);
- } while (--repeat > 0);
-
- dev_err(&data->client->dev, "failed to disable power: %d\n", error);
+ dev_err(&data->client->dev, "failed to set power %s: %d\n",
+ on ? "on" : "off", error);
return error;
}
@@ -216,8 +195,13 @@
if (error)
return error;
- error = data->ops->get_sm_version(data->client, &data->ic_type,
- &data->sm_version, &data->clickpad);
+ error = data->ops->get_pattern(data->client, &data->pattern);
+ if (error)
+ return error;
+
+ error = data->ops->get_sm_version(data->client, data->pattern,
+ &data->ic_type, &data->sm_version,
+ &data->clickpad);
if (error)
return error;
@@ -313,9 +297,9 @@
static int elan_query_device_info(struct elan_tp_data *data)
{
int error;
- u16 ic_type;
- error = data->ops->get_version(data->client, false, &data->fw_version);
+ error = data->ops->get_version(data->client, data->pattern, false,
+ &data->fw_version);
if (error)
return error;
@@ -324,7 +308,8 @@
if (error)
return error;
- error = data->ops->get_version(data->client, true, &data->iap_version);
+ error = data->ops->get_version(data->client, data->pattern,
+ true, &data->iap_version);
if (error)
return error;
@@ -333,17 +318,16 @@
if (error)
return error;
- error = data->ops->get_pattern(data->client, &data->pattern);
+ error = data->ops->get_report_features(data->client, data->pattern,
+ &data->report_features,
+ &data->report_len);
if (error)
return error;
- if (data->pattern == 0x01)
- ic_type = data->ic_type;
- else
- ic_type = data->iap_version;
-
- error = elan_get_fwinfo(ic_type, &data->fw_validpage_count,
- &data->fw_signature_address);
+ error = elan_get_fwinfo(data->ic_type, data->iap_version,
+ &data->fw_validpage_count,
+ &data->fw_signature_address,
+ &data->fw_page_size);
if (error)
dev_warn(&data->client->dev,
"unexpected iap version %#04x (ic type: %#04x), firmware update will not work\n",
@@ -352,41 +336,81 @@
return 0;
}
-static unsigned int elan_convert_resolution(u8 val)
+static unsigned int elan_convert_resolution(u8 val, u8 pattern)
{
/*
- * (value from firmware) * 10 + 790 = dpi
- *
+ * pattern <= 0x01:
+ * (value from firmware) * 10 + 790 = dpi
+ * else
+ * ((value from firmware) + 3) * 100 = dpi
+ */
+ int res = pattern <= 0x01 ?
+ (int)(char)val * 10 + 790 : ((int)(char)val + 3) * 100;
+ /*
* We also have to convert dpi to dots/mm (*10/254 to avoid floating
* point).
*/
-
- return ((int)(char)val * 10 + 790) * 10 / 254;
+ return res * 10 / 254;
}
static int elan_query_device_parameters(struct elan_tp_data *data)
{
+ struct i2c_client *client = data->client;
unsigned int x_traces, y_traces;
+ u32 x_mm, y_mm;
u8 hw_x_res, hw_y_res;
int error;
- error = data->ops->get_max(data->client, &data->max_x, &data->max_y);
- if (error)
- return error;
+ if (device_property_read_u32(&client->dev,
+ "touchscreen-size-x", &data->max_x) ||
+ device_property_read_u32(&client->dev,
+ "touchscreen-size-y", &data->max_y)) {
+ error = data->ops->get_max(data->client,
+ &data->max_x,
+ &data->max_y);
+ if (error)
+ return error;
+ } else {
+ /* size is the maximum + 1 */
+ --data->max_x;
+ --data->max_y;
+ }
- error = data->ops->get_num_traces(data->client, &x_traces, &y_traces);
- if (error)
- return error;
-
+ if (device_property_read_u32(&client->dev,
+ "elan,x_traces",
+ &x_traces) ||
+ device_property_read_u32(&client->dev,
+ "elan,y_traces",
+ &y_traces)) {
+ error = data->ops->get_num_traces(data->client,
+ &x_traces, &y_traces);
+ if (error)
+ return error;
+ }
data->width_x = data->max_x / x_traces;
data->width_y = data->max_y / y_traces;
- error = data->ops->get_resolution(data->client, &hw_x_res, &hw_y_res);
- if (error)
- return error;
+ if (device_property_read_u32(&client->dev,
+ "touchscreen-x-mm", &x_mm) ||
+ device_property_read_u32(&client->dev,
+ "touchscreen-y-mm", &y_mm)) {
+ error = data->ops->get_resolution(data->client,
+ &hw_x_res, &hw_y_res);
+ if (error)
+ return error;
- data->x_res = elan_convert_resolution(hw_x_res);
- data->y_res = elan_convert_resolution(hw_y_res);
+ data->x_res = elan_convert_resolution(hw_x_res, data->pattern);
+ data->y_res = elan_convert_resolution(hw_y_res, data->pattern);
+ } else {
+ data->x_res = (data->max_x + 1) / x_mm;
+ data->y_res = (data->max_y + 1) / y_mm;
+ }
+
+ if (device_property_read_bool(&client->dev, "elan,clickpad"))
+ data->clickpad = 1;
+
+ if (device_property_read_bool(&client->dev, "elan,middle-button"))
+ data->middle_button = true;
return 0;
}
@@ -396,14 +420,14 @@
* IAP firmware updater related routines
**********************************************************
*/
-static int elan_write_fw_block(struct elan_tp_data *data,
+static int elan_write_fw_block(struct elan_tp_data *data, u16 page_size,
const u8 *page, u16 checksum, int idx)
{
int retry = ETP_RETRY_COUNT;
int error;
do {
- error = data->ops->write_fw_block(data->client,
+ error = data->ops->write_fw_block(data->client, page_size,
page, checksum, idx);
if (!error)
return 0;
@@ -426,21 +450,24 @@
u16 boot_page_count;
u16 sw_checksum = 0, fw_checksum = 0;
- error = data->ops->prepare_fw_update(client);
+ error = data->ops->prepare_fw_update(client, data->ic_type,
+ data->iap_version,
+ data->fw_page_size);
if (error)
return error;
iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]);
- boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE;
+ boot_page_count = (iap_start_addr * 2) / data->fw_page_size;
for (i = boot_page_count; i < data->fw_validpage_count; i++) {
u16 checksum = 0;
- const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE];
+ const u8 *page = &fw->data[i * data->fw_page_size];
- for (j = 0; j < ETP_FW_PAGE_SIZE; j += 2)
+ for (j = 0; j < data->fw_page_size; j += 2)
checksum += ((page[j + 1] << 8) | page[j]);
- error = elan_write_fw_block(data, page, checksum, i);
+ error = elan_write_fw_block(data, data->fw_page_size,
+ page, checksum, i);
if (error) {
dev_err(dev, "write page %d fail: %d\n", i, error);
return error;
@@ -852,24 +879,22 @@
* Elan isr functions
******************************************************************
*/
-static void elan_report_contact(struct elan_tp_data *data,
- int contact_num, bool contact_valid,
- u8 *finger_data)
+static void elan_report_contact(struct elan_tp_data *data, int contact_num,
+ bool contact_valid, bool high_precision,
+ u8 *packet, u8 *finger_data)
{
struct input_dev *input = data->input;
unsigned int pos_x, pos_y;
- unsigned int pressure, mk_x, mk_y;
- unsigned int area_x, area_y, major, minor;
- unsigned int scaled_pressure;
+ unsigned int pressure, scaled_pressure;
if (contact_valid) {
- pos_x = ((finger_data[0] & 0xf0) << 4) |
- finger_data[1];
- pos_y = ((finger_data[0] & 0x0f) << 8) |
- finger_data[2];
- mk_x = (finger_data[3] & 0x0f);
- mk_y = (finger_data[3] >> 4);
- pressure = finger_data[4];
+ if (high_precision) {
+ pos_x = get_unaligned_be16(&finger_data[0]);
+ pos_y = get_unaligned_be16(&finger_data[2]);
+ } else {
+ pos_x = ((finger_data[0] & 0xf0) << 4) | finger_data[1];
+ pos_y = ((finger_data[0] & 0x0f) << 8) | finger_data[2];
+ }
if (pos_x > data->max_x || pos_y > data->max_y) {
dev_dbg(input->dev.parent,
@@ -879,18 +904,8 @@
return;
}
- /*
- * To avoid treating large finger as palm, let's reduce the
- * width x and y per trace.
- */
- area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE);
- area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE);
-
- major = max(area_x, area_y);
- minor = min(area_x, area_y);
-
+ pressure = finger_data[4];
scaled_pressure = pressure + data->pressure_adjustment;
-
if (scaled_pressure > ETP_MAX_PRESSURE)
scaled_pressure = ETP_MAX_PRESSURE;
@@ -899,16 +914,37 @@
input_report_abs(input, ABS_MT_POSITION_X, pos_x);
input_report_abs(input, ABS_MT_POSITION_Y, data->max_y - pos_y);
input_report_abs(input, ABS_MT_PRESSURE, scaled_pressure);
- input_report_abs(input, ABS_TOOL_WIDTH, mk_x);
- input_report_abs(input, ABS_MT_TOUCH_MAJOR, major);
- input_report_abs(input, ABS_MT_TOUCH_MINOR, minor);
+
+ if (data->report_features & ETP_FEATURE_REPORT_MK) {
+ unsigned int mk_x, mk_y, area_x, area_y;
+ u8 mk_data = high_precision ?
+ packet[ETP_MK_DATA_OFFSET + contact_num] :
+ finger_data[3];
+
+ mk_x = mk_data & 0x0f;
+ mk_y = mk_data >> 4;
+
+ /*
+ * To avoid treating large finger as palm, let's reduce
+ * the width x and y per trace.
+ */
+ area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE);
+ area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE);
+
+ input_report_abs(input, ABS_TOOL_WIDTH, mk_x);
+ input_report_abs(input, ABS_MT_TOUCH_MAJOR,
+ max(area_x, area_y));
+ input_report_abs(input, ABS_MT_TOUCH_MINOR,
+ min(area_x, area_y));
+ }
} else {
input_mt_slot(input, contact_num);
- input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
+ input_mt_report_slot_inactive(input);
}
}
-static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
+static void elan_report_absolute(struct elan_tp_data *data, u8 *packet,
+ bool high_precision)
{
struct input_dev *input = data->input;
u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET];
@@ -917,17 +953,21 @@
u8 hover_info = packet[ETP_HOVER_INFO_OFFSET];
bool contact_valid, hover_event;
- hover_event = hover_info & 0x40;
- for (i = 0; i < ETP_MAX_FINGERS; i++) {
- contact_valid = tp_info & (1U << (3 + i));
- elan_report_contact(data, i, contact_valid, finger_data);
+ pm_wakeup_event(&data->client->dev, 0);
+ hover_event = hover_info & BIT(6);
+
+ for (i = 0; i < ETP_MAX_FINGERS; i++) {
+ contact_valid = tp_info & BIT(3 + i);
+ elan_report_contact(data, i, contact_valid, high_precision,
+ packet, finger_data);
if (contact_valid)
finger_data += ETP_FINGER_DATA_LEN;
}
- input_report_key(input, BTN_LEFT, tp_info & 0x01);
- input_report_key(input, BTN_RIGHT, tp_info & 0x02);
+ input_report_key(input, BTN_LEFT, tp_info & BIT(0));
+ input_report_key(input, BTN_MIDDLE, tp_info & BIT(2));
+ input_report_key(input, BTN_RIGHT, tp_info & BIT(1));
input_report_abs(input, ABS_DISTANCE, hover_event != 0);
input_mt_report_pointer_emulation(input, true);
input_sync(input);
@@ -938,6 +978,8 @@
struct input_dev *input = data->tp_input;
u8 *packet = &report[ETP_REPORT_ID_OFFSET + 1];
int x, y;
+
+ pm_wakeup_event(&data->client->dev, 0);
if (!data->tp_input) {
dev_warn_once(&data->client->dev,
@@ -963,7 +1005,6 @@
static irqreturn_t elan_isr(int irq, void *dev_id)
{
struct elan_tp_data *data = dev_id;
- struct device *dev = &data->client->dev;
int error;
u8 report[ETP_MAX_REPORT_LEN];
@@ -977,19 +1018,23 @@
goto out;
}
- error = data->ops->get_report(data->client, report);
+ error = data->ops->get_report(data->client, report, data->report_len);
if (error)
goto out;
switch (report[ETP_REPORT_ID_OFFSET]) {
case ETP_REPORT_ID:
- elan_report_absolute(data, report);
+ elan_report_absolute(data, report, false);
+ break;
+ case ETP_REPORT_ID2:
+ elan_report_absolute(data, report, true);
break;
case ETP_TP_REPORT_ID:
+ case ETP_TP_REPORT_ID2:
elan_report_trackpoint(data, report);
break;
default:
- dev_err(dev, "invalid report id data (%x)\n",
+ dev_err(&data->client->dev, "invalid report id data (%x)\n",
report[ETP_REPORT_ID_OFFSET]);
}
@@ -1059,10 +1104,13 @@
__set_bit(EV_ABS, input->evbit);
__set_bit(INPUT_PROP_POINTER, input->propbit);
- if (data->clickpad)
+ if (data->clickpad) {
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
- else
+ } else {
__set_bit(BTN_RIGHT, input->keybit);
+ if (data->middle_button)
+ __set_bit(BTN_MIDDLE, input->keybit);
+ }
__set_bit(BTN_LEFT, input->keybit);
/* Set up ST parameters */
@@ -1071,7 +1119,9 @@
input_abs_set_res(input, ABS_X, data->x_res);
input_abs_set_res(input, ABS_Y, data->y_res);
input_set_abs_params(input, ABS_PRESSURE, 0, ETP_MAX_PRESSURE, 0, 0);
- input_set_abs_params(input, ABS_TOOL_WIDTH, 0, ETP_FINGER_WIDTH, 0, 0);
+ if (data->report_features & ETP_FEATURE_REPORT_MK)
+ input_set_abs_params(input, ABS_TOOL_WIDTH,
+ 0, ETP_FINGER_WIDTH, 0, 0);
input_set_abs_params(input, ABS_DISTANCE, 0, 1, 0, 0);
/* And MT parameters */
@@ -1081,10 +1131,12 @@
input_abs_set_res(input, ABS_MT_POSITION_Y, data->y_res);
input_set_abs_params(input, ABS_MT_PRESSURE, 0,
ETP_MAX_PRESSURE, 0, 0);
- input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0,
- ETP_FINGER_WIDTH * max_width, 0, 0);
- input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0,
- ETP_FINGER_WIDTH * min_width, 0, 0);
+ if (data->report_features & ETP_FEATURE_REPORT_MK) {
+ input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,
+ 0, ETP_FINGER_WIDTH * max_width, 0, 0);
+ input_set_abs_params(input, ABS_MT_TOUCH_MINOR,
+ 0, ETP_FINGER_WIDTH * min_width, 0, 0);
+ }
data->input = input;
@@ -1096,13 +1148,6 @@
struct elan_tp_data *data = _data;
regulator_disable(data->vcc);
-}
-
-static void elan_remove_sysfs_groups(void *_data)
-{
- struct elan_tp_data *data = _data;
-
- sysfs_remove_groups(&data->client->dev.kobj, elan_sysfs_groups);
}
static int elan_probe(struct i2c_client *client,
@@ -1154,9 +1199,8 @@
return error;
}
- error = devm_add_action(dev, elan_disable_regulator, data);
+ error = devm_add_action_or_reset(dev, elan_disable_regulator, data);
if (error) {
- regulator_disable(data->vcc);
dev_err(dev, "Failed to add disable regulator action: %d\n",
error);
return error;
@@ -1229,17 +1273,9 @@
return error;
}
- error = sysfs_create_groups(&dev->kobj, elan_sysfs_groups);
+ error = devm_device_add_groups(dev, elan_sysfs_groups);
if (error) {
dev_err(dev, "failed to create sysfs attributes: %d\n", error);
- return error;
- }
-
- error = devm_add_action(dev, elan_remove_sysfs_groups, data);
- if (error) {
- elan_remove_sysfs_groups(data);
- dev_err(dev, "Failed to add sysfs cleanup action: %d\n",
- error);
return error;
}
@@ -1291,9 +1327,19 @@
/* Enable wake from IRQ */
data->irq_wake = (enable_irq_wake(client->irq) == 0);
} else {
- ret = elan_disable_power(data);
+ ret = elan_set_power(data, false);
+ if (ret)
+ goto err;
+
+ ret = regulator_disable(data->vcc);
+ if (ret) {
+ dev_err(dev, "error %d disabling regulator\n", ret);
+ /* Attempt to power the chip back up */
+ elan_set_power(data, true);
+ }
}
+err:
mutex_unlock(&data->sysfs_mutex);
return ret;
}
@@ -1304,12 +1350,18 @@
struct elan_tp_data *data = i2c_get_clientdata(client);
int error;
- if (device_may_wakeup(dev) && data->irq_wake) {
+ if (!device_may_wakeup(dev)) {
+ error = regulator_enable(data->vcc);
+ if (error) {
+ dev_err(dev, "error %d enabling regulator\n", error);
+ goto err;
+ }
+ } else if (data->irq_wake) {
disable_irq_wake(client->irq);
data->irq_wake = false;
}
- error = elan_enable_power(data);
+ error = elan_set_power(data, true);
if (error) {
dev_err(dev, "power up when resuming failed: %d\n", error);
goto err;
@@ -1333,55 +1385,6 @@
MODULE_DEVICE_TABLE(i2c, elan_id);
#ifdef CONFIG_ACPI
-static const struct acpi_device_id elan_acpi_id[] = {
- { "ELAN0000", 0 },
- { "ELAN0100", 0 },
- { "ELAN0600", 0 },
- { "ELAN0601", 0 },
- { "ELAN0602", 0 },
- { "ELAN0603", 0 },
- { "ELAN0604", 0 },
- { "ELAN0605", 0 },
- { "ELAN0606", 0 },
- { "ELAN0607", 0 },
- { "ELAN0608", 0 },
- { "ELAN0609", 0 },
- { "ELAN060B", 0 },
- { "ELAN060C", 0 },
- { "ELAN060F", 0 },
- { "ELAN0610", 0 },
- { "ELAN0611", 0 },
- { "ELAN0612", 0 },
- { "ELAN0615", 0 },
- { "ELAN0616", 0 },
- { "ELAN0617", 0 },
- { "ELAN0618", 0 },
- { "ELAN0619", 0 },
- { "ELAN061A", 0 },
-/* { "ELAN061B", 0 }, not working on the Lenovo Legion Y7000 */
- { "ELAN061C", 0 },
- { "ELAN061D", 0 },
- { "ELAN061E", 0 },
- { "ELAN061F", 0 },
- { "ELAN0620", 0 },
- { "ELAN0621", 0 },
- { "ELAN0622", 0 },
- { "ELAN0623", 0 },
- { "ELAN0624", 0 },
- { "ELAN0625", 0 },
- { "ELAN0626", 0 },
- { "ELAN0627", 0 },
- { "ELAN0628", 0 },
- { "ELAN0629", 0 },
- { "ELAN062A", 0 },
- { "ELAN062B", 0 },
- { "ELAN062C", 0 },
- { "ELAN062D", 0 },
- { "ELAN0631", 0 },
- { "ELAN0632", 0 },
- { "ELAN1000", 0 },
- { }
-};
MODULE_DEVICE_TABLE(acpi, elan_acpi_id);
#endif
--
Gitblit v1.6.2