* [PATCH 1/6] ideapad: add platform driver for ideapad
2010-12-13 9:59 [PATCH v3 0/6] ideapad: hotkey enablement Ike Panhc
@ 2010-12-13 10:00 ` Ike Panhc
2010-12-13 10:00 ` [PATCH 2/6] ideapad: let camera power control entry under platform driver Ike Panhc
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ike Panhc @ 2010-12-13 10:00 UTC (permalink / raw)
To: linux-kernel, platform-driver-x86, linux-acpi
Cc: Matthew Garrett, David Woodhouse, Dmitry Torokhov, Dave Hansen,
Corentin Chary
Create /sys/devices/platform/ideapad for nodes of ideapad landing.
Signed-off-by: Ike Panhc <ike.pan@canonical.com>
---
drivers/platform/x86/ideapad-laptop.c | 54 ++++++++++++++++++++++++++++----
1 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 5ff1220..5998ae1 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -27,6 +27,7 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <linux/rfkill.h>
+#include <linux/platform_device.h>
#define IDEAPAD_DEV_CAMERA 0
#define IDEAPAD_DEV_WLAN 1
@@ -37,6 +38,7 @@
struct ideapad_private {
acpi_handle handle;
struct rfkill *rfk[5];
+ struct platform_device *platform_device;
} *ideapad_priv;
static struct {
@@ -277,6 +279,35 @@ static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev)
rfkill_destroy(priv->rfk[dev]);
}
+/*
+ * Platform device
+ */
+static int __devinit ideapad_platform_init(void)
+{
+ int result;
+
+ ideapad_priv->platform_device = platform_device_alloc("ideapad", -1);
+ if (!ideapad_priv->platform_device)
+ return -ENOMEM;
+ platform_set_drvdata(ideapad_priv->platform_device, ideapad_priv);
+
+ result = platform_device_add(ideapad_priv->platform_device);
+ if (result)
+ goto fail_platform_device;
+
+ return 0;
+
+fail_platform_device:
+ platform_device_put(ideapad_priv->platform_device);
+ return result;
+}
+
+static void ideapad_platform_exit(void)
+{
+ platform_device_unregister(ideapad_priv->platform_device);
+}
+/* the above is platform device */
+
static const struct acpi_device_id ideapad_device_ids[] = {
{ "VPC2004", 0},
{ "", 0},
@@ -285,7 +316,7 @@ MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
static int ideapad_acpi_add(struct acpi_device *adevice)
{
- int i, cfg;
+ int ret, i, cfg;
int devs_present[5];
struct ideapad_private *priv;
@@ -305,18 +336,20 @@ static int ideapad_acpi_add(struct acpi_device *adevice)
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
+ ideapad_priv = priv;
+
+ ret = ideapad_platform_init();
+ if (ret)
+ goto platform_failed;
if (devs_present[IDEAPAD_DEV_CAMERA]) {
- int ret = device_create_file(&adevice->dev, &dev_attr_camera_power);
- if (ret) {
- kfree(priv);
- return ret;
- }
+ ret = device_create_file(&adevice->dev, &dev_attr_camera_power);
+ if (ret)
+ goto camera_failed;
}
priv->handle = adevice->handle;
dev_set_drvdata(&adevice->dev, priv);
- ideapad_priv = priv;
for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) {
if (!devs_present[i])
continue;
@@ -325,6 +358,12 @@ static int ideapad_acpi_add(struct acpi_device *adevice)
}
ideapad_sync_rfk_state(adevice);
return 0;
+
+camera_failed:
+ ideapad_platform_exit();
+platform_failed:
+ kfree(priv);
+ return ret;
}
static int ideapad_acpi_remove(struct acpi_device *adevice, int type)
@@ -337,6 +376,7 @@ static int ideapad_acpi_remove(struct acpi_device *adevice, int type)
for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++)
ideapad_unregister_rfkill(adevice, i);
+ ideapad_platform_exit();
dev_set_drvdata(&adevice->dev, NULL);
kfree(priv);
return 0;
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 2/6] ideapad: let camera power control entry under platform driver
2010-12-13 9:59 [PATCH v3 0/6] ideapad: hotkey enablement Ike Panhc
2010-12-13 10:00 ` [PATCH 1/6] ideapad: add platform driver for ideapad Ike Panhc
@ 2010-12-13 10:00 ` Ike Panhc
2010-12-13 10:00 ` [PATCH 3/6] ideapad: add hotkey support Ike Panhc
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ike Panhc @ 2010-12-13 10:00 UTC (permalink / raw)
To: linux-kernel, platform-driver-x86, linux-acpi
Cc: Matthew Garrett, David Woodhouse, Dmitry Torokhov, Dave Hansen,
Corentin Chary
The entry was at /sys/devices/LNXSYSTM:00/../VPC2004:00/camera_power
move to /sys/devices/platform/ideapad/camera_power
Add document about usage of ideapad node in sysfs.
Signed-off-by: Ike Panhc <ike.pan@canonical.com>
---
.../ABI/testing/sysfs-platform-ideapad-laptop | 6 ++
drivers/platform/x86/ideapad-laptop.c | 55 +++++++++-----------
2 files changed, 31 insertions(+), 30 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-platform-ideapad-laptop
diff --git a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop
new file mode 100644
index 0000000..807fca2
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop
@@ -0,0 +1,6 @@
+What: /sys/devices/platform/ideapad/camera_power
+Date: Dec 2010
+KernelVersion: 2.6.37
+Contact: "Ike Panhc <ike.pan@canonical.com>"
+Description:
+ Control the power of camera module. 1 means on, 0 means off.
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 5998ae1..49f207f 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -282,6 +282,15 @@ static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev)
/*
* Platform device
*/
+static struct attribute *ideapad_attributes[] = {
+ &dev_attr_camera_power.attr,
+ NULL
+};
+
+static struct attribute_group ideapad_attribute_group = {
+ .attrs = ideapad_attributes
+};
+
static int __devinit ideapad_platform_init(void)
{
int result;
@@ -295,8 +304,14 @@ static int __devinit ideapad_platform_init(void)
if (result)
goto fail_platform_device;
+ result = sysfs_create_group(&ideapad_priv->platform_device->dev.kobj,
+ &ideapad_attribute_group);
+ if (result)
+ goto fail_sysfs;
return 0;
+fail_sysfs:
+ platform_device_del(ideapad_priv->platform_device);
fail_platform_device:
platform_device_put(ideapad_priv->platform_device);
return result;
@@ -304,6 +319,8 @@ fail_platform_device:
static void ideapad_platform_exit(void)
{
+ sysfs_remove_group(&ideapad_priv->platform_device->dev.kobj,
+ &ideapad_attribute_group);
platform_device_unregister(ideapad_priv->platform_device);
}
/* the above is platform device */
@@ -317,50 +334,30 @@ MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
static int ideapad_acpi_add(struct acpi_device *adevice)
{
int ret, i, cfg;
- int devs_present[5];
struct ideapad_private *priv;
if (read_method_int(adevice->handle, "_CFG", &cfg))
return -ENODEV;
- for (i = IDEAPAD_DEV_CAMERA; i < IDEAPAD_DEV_KILLSW; i++) {
- if (test_bit(ideapad_rfk_data[i].cfgbit, (unsigned long *)&cfg))
- devs_present[i] = 1;
- else
- devs_present[i] = 0;
- }
-
- /* The hardware switch is always present */
- devs_present[IDEAPAD_DEV_KILLSW] = 1;
-
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
ideapad_priv = priv;
+ priv->handle = adevice->handle;
+ dev_set_drvdata(&adevice->dev, priv);
ret = ideapad_platform_init();
if (ret)
goto platform_failed;
- if (devs_present[IDEAPAD_DEV_CAMERA]) {
- ret = device_create_file(&adevice->dev, &dev_attr_camera_power);
- if (ret)
- goto camera_failed;
- }
-
- priv->handle = adevice->handle;
- dev_set_drvdata(&adevice->dev, priv);
- for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) {
- if (!devs_present[i])
- continue;
-
- ideapad_register_rfkill(adevice, i);
+ for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++) {
+ if (test_bit(ideapad_rfk_data[i].cfgbit, (unsigned long *)&cfg))
+ ideapad_register_rfkill(adevice, i);
}
ideapad_sync_rfk_state(adevice);
+
return 0;
-camera_failed:
- ideapad_platform_exit();
platform_failed:
kfree(priv);
return ret;
@@ -371,14 +368,12 @@ static int ideapad_acpi_remove(struct acpi_device *adevice, int type)
struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
int i;
- device_remove_file(&adevice->dev, &dev_attr_camera_power);
-
- for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++)
+ for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++)
ideapad_unregister_rfkill(adevice, i);
-
ideapad_platform_exit();
dev_set_drvdata(&adevice->dev, NULL);
kfree(priv);
+
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 3/6] ideapad: add hotkey support
2010-12-13 9:59 [PATCH v3 0/6] ideapad: hotkey enablement Ike Panhc
2010-12-13 10:00 ` [PATCH 1/6] ideapad: add platform driver for ideapad Ike Panhc
2010-12-13 10:00 ` [PATCH 2/6] ideapad: let camera power control entry under platform driver Ike Panhc
@ 2010-12-13 10:00 ` Ike Panhc
2010-12-13 10:00 ` [PATCH 4/6] ideapad: add markups, unify comments and return result when init Ike Panhc
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ike Panhc @ 2010-12-13 10:00 UTC (permalink / raw)
To: linux-kernel, platform-driver-x86, linux-acpi
Cc: Matthew Garrett, David Woodhouse, Dmitry Torokhov, Dave Hansen,
Corentin Chary
Hotkey enabled by this patch:
Fn+F3: Video mode switch
Fn+F5: software rfkill for wifi
For some ideapad when push Fn+F3, hardware generates Super-P keys, those key
will not be enabled by this patch.
Thanks for Dave Hansen report the problem. If CONFIG_INPUT_SPARSEKMAP is not
set, when building, you will have error message:
ERROR: "sparse_keymap_setup" [drivers/platform/x86/ideapad-laptop.ko] undefined!
ERROR: "sparse_keymap_free" [drivers/platform/x86/ideapad-laptop.ko] undefined!
ERROR: "sparse_keymap_report_event" [drivers/platform/x86/ideapad-laptop.ko] undefined!
To select INPUT_SPARSEKMAP solve this issue.
Ref: http://lkml.org/lkml/2010/12/2/340
Signed-off-by: Ike Panhc <ike.pan@canonical.com>
---
drivers/platform/x86/Kconfig | 1 +
drivers/platform/x86/ideapad-laptop.c | 72 +++++++++++++++++++++++++++++++++
2 files changed, 73 insertions(+), 0 deletions(-)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index faec777..879d266 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -226,6 +226,7 @@ config IDEAPAD_LAPTOP
tristate "Lenovo IdeaPad Laptop Extras"
depends on ACPI
depends on RFKILL
+ select INPUT_SPARSEKMAP
help
This is a driver for the rfkill switches on Lenovo IdeaPad netbooks.
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 49f207f..04b4f5b 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -28,6 +28,8 @@
#include <acpi/acpi_drivers.h>
#include <linux/rfkill.h>
#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#define IDEAPAD_DEV_CAMERA 0
#define IDEAPAD_DEV_WLAN 1
@@ -39,6 +41,7 @@ struct ideapad_private {
acpi_handle handle;
struct rfkill *rfk[5];
struct platform_device *platform_device;
+ struct input_dev *inputdev;
} *ideapad_priv;
static struct {
@@ -325,6 +328,66 @@ static void ideapad_platform_exit(void)
}
/* the above is platform device */
+/*
+ * input device
+ */
+static const struct key_entry ideapad_keymap[] = {
+ { KE_KEY, 0x06, { KEY_SWITCHVIDEOMODE } },
+ { KE_KEY, 0x0D, { KEY_WLAN } },
+ { KE_END, 0 },
+};
+
+static int __devinit ideapad_input_init(void)
+{
+ struct input_dev *inputdev;
+ int error;
+
+ inputdev = input_allocate_device();
+ if (!inputdev) {
+ pr_info("Unable to allocate input device\n");
+ return -ENOMEM;
+ }
+
+ inputdev->name = "Ideapad extra buttons";
+ inputdev->phys = "ideapad/input0";
+ inputdev->id.bustype = BUS_HOST;
+ inputdev->dev.parent = &ideapad_priv->platform_device->dev;
+
+ error = sparse_keymap_setup(inputdev, ideapad_keymap, NULL);
+ if (error) {
+ pr_err("Unable to setup input device keymap\n");
+ goto err_free_dev;
+ }
+
+ error = input_register_device(inputdev);
+ if (error) {
+ pr_err("Unable to register input device\n");
+ goto err_free_keymap;
+ }
+
+ ideapad_priv->inputdev = inputdev;
+ return 0;
+
+err_free_keymap:
+ sparse_keymap_free(inputdev);
+err_free_dev:
+ input_free_device(inputdev);
+ return error;
+}
+
+static void __devexit ideapad_input_exit(void)
+{
+ sparse_keymap_free(ideapad_priv->inputdev);
+ input_unregister_device(ideapad_priv->inputdev);
+ ideapad_priv->inputdev = NULL;
+}
+
+static void ideapad_input_report(unsigned long scancode)
+{
+ sparse_keymap_report_event(ideapad_priv->inputdev, scancode, 1, true);
+}
+/* the above is input device */
+
static const struct acpi_device_id ideapad_device_ids[] = {
{ "VPC2004", 0},
{ "", 0},
@@ -350,6 +413,10 @@ static int ideapad_acpi_add(struct acpi_device *adevice)
if (ret)
goto platform_failed;
+ ret = ideapad_input_init();
+ if (ret)
+ goto input_failed;
+
for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++) {
if (test_bit(ideapad_rfk_data[i].cfgbit, (unsigned long *)&cfg))
ideapad_register_rfkill(adevice, i);
@@ -358,6 +425,8 @@ static int ideapad_acpi_add(struct acpi_device *adevice)
return 0;
+input_failed:
+ ideapad_platform_exit();
platform_failed:
kfree(priv);
return ret;
@@ -370,6 +439,7 @@ static int ideapad_acpi_remove(struct acpi_device *adevice, int type)
for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++)
ideapad_unregister_rfkill(adevice, i);
+ ideapad_input_exit();
ideapad_platform_exit();
dev_set_drvdata(&adevice->dev, NULL);
kfree(priv);
@@ -392,6 +462,8 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
if (test_bit(vpc_bit, &vpc1)) {
if (vpc_bit == 9)
ideapad_sync_rfk_state(adevice);
+ else
+ ideapad_input_report(vpc_bit);
}
}
}
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/6] ideapad: add markups, unify comments and return result when init
2010-12-13 9:59 [PATCH v3 0/6] ideapad: hotkey enablement Ike Panhc
` (2 preceding siblings ...)
2010-12-13 10:00 ` [PATCH 3/6] ideapad: add hotkey support Ike Panhc
@ 2010-12-13 10:00 ` Ike Panhc
2010-12-13 10:01 ` [PATCH 5/6] ideapad: pass ideapad_priv as argument (part 1) Ike Panhc
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ike Panhc @ 2010-12-13 10:00 UTC (permalink / raw)
To: linux-kernel, platform-driver-x86, linux-acpi
Cc: Matthew Garrett, David Woodhouse, Dmitry Torokhov, Dave Hansen,
Corentin Chary
1. Add markups on init and exit functions
2. Unify the comments in the same style
3. Return result when module initial
Signed-off-by: Ike Panhc <ike.pan@canonical.com>
---
drivers/platform/x86/ideapad-laptop.c | 31 +++++++++++++++++--------------
1 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 04b4f5b..3c6c5b5 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -1,5 +1,5 @@
/*
- * ideapad_acpi.c - Lenovo IdeaPad ACPI Extras
+ * ideapad-laptop.c - Lenovo IdeaPad ACPI Extras
*
* Copyright © 2010 Intel Corporation
* Copyright © 2010 David Woodhouse <dwmw2@infradead.org>
@@ -168,8 +168,10 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data)
pr_err("timeout in write_ec_cmd\n");
return -1;
}
-/* the above is ACPI helpers */
+/*
+ * camera power
+ */
static ssize_t show_ideapad_cam(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -203,6 +205,9 @@ static ssize_t store_ideapad_cam(struct device *dev,
static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam);
+/*
+ * Rfkill
+ */
static int ideapad_rfk_set(void *data, bool blocked)
{
int device = (unsigned long)data;
@@ -235,7 +240,8 @@ static void ideapad_sync_rfk_state(struct acpi_device *adevice)
rfkill_set_hw_state(priv->rfk[i], hw_blocked);
}
-static int ideapad_register_rfkill(struct acpi_device *adevice, int dev)
+static int __devinit ideapad_register_rfkill(struct acpi_device *adevice,
+ int dev)
{
struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
int ret;
@@ -271,7 +277,8 @@ static int ideapad_register_rfkill(struct acpi_device *adevice, int dev)
return 0;
}
-static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev)
+static void __devexit ideapad_unregister_rfkill(struct acpi_device *adevice,
+ int dev)
{
struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
@@ -326,7 +333,6 @@ static void ideapad_platform_exit(void)
&ideapad_attribute_group);
platform_device_unregister(ideapad_priv->platform_device);
}
-/* the above is platform device */
/*
* input device
@@ -386,15 +392,17 @@ static void ideapad_input_report(unsigned long scancode)
{
sparse_keymap_report_event(ideapad_priv->inputdev, scancode, 1, true);
}
-/* the above is input device */
+/*
+ * module init/exit
+ */
static const struct acpi_device_id ideapad_device_ids[] = {
{ "VPC2004", 0},
{ "", 0},
};
MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
-static int ideapad_acpi_add(struct acpi_device *adevice)
+static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
{
int ret, i, cfg;
struct ideapad_private *priv;
@@ -432,7 +440,7 @@ platform_failed:
return ret;
}
-static int ideapad_acpi_remove(struct acpi_device *adevice, int type)
+static int __devexit ideapad_acpi_remove(struct acpi_device *adevice, int type)
{
struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
int i;
@@ -478,19 +486,14 @@ static struct acpi_driver ideapad_acpi_driver = {
.owner = THIS_MODULE,
};
-
static int __init ideapad_acpi_module_init(void)
{
- acpi_bus_register_driver(&ideapad_acpi_driver);
-
- return 0;
+ return acpi_bus_register_driver(&ideapad_acpi_driver);
}
-
static void __exit ideapad_acpi_module_exit(void)
{
acpi_bus_unregister_driver(&ideapad_acpi_driver);
-
}
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 5/6] ideapad: pass ideapad_priv as argument (part 1)
2010-12-13 9:59 [PATCH v3 0/6] ideapad: hotkey enablement Ike Panhc
` (3 preceding siblings ...)
2010-12-13 10:00 ` [PATCH 4/6] ideapad: add markups, unify comments and return result when init Ike Panhc
@ 2010-12-13 10:01 ` Ike Panhc
2010-12-13 10:01 ` [PATCH 6/6] ideapad: pass ideapad_priv as argument (part 2) Ike Panhc
2010-12-20 16:14 ` [PATCH v3 0/6] ideapad: hotkey enablement Matthew Garrett
6 siblings, 0 replies; 8+ messages in thread
From: Ike Panhc @ 2010-12-13 10:01 UTC (permalink / raw)
To: linux-kernel, platform-driver-x86, linux-acpi
Cc: Matthew Garrett, David Woodhouse, Dmitry Torokhov, Dave Hansen,
Corentin Chary
Passing ideapad_priv as argument and try not to using too much global variable.
This is part 1 for platform driver and input device.
Signed-off-by: Ike Panhc <ike.pan@canonical.com>
---
drivers/platform/x86/ideapad-laptop.c | 54 +++++++++++++++++----------------
1 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 3c6c5b5..37fe0d0 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -301,37 +301,37 @@ static struct attribute_group ideapad_attribute_group = {
.attrs = ideapad_attributes
};
-static int __devinit ideapad_platform_init(void)
+static int __devinit ideapad_platform_init(struct ideapad_private *priv)
{
int result;
- ideapad_priv->platform_device = platform_device_alloc("ideapad", -1);
- if (!ideapad_priv->platform_device)
+ priv->platform_device = platform_device_alloc("ideapad", -1);
+ if (!priv->platform_device)
return -ENOMEM;
- platform_set_drvdata(ideapad_priv->platform_device, ideapad_priv);
+ platform_set_drvdata(priv->platform_device, priv);
- result = platform_device_add(ideapad_priv->platform_device);
+ result = platform_device_add(priv->platform_device);
if (result)
goto fail_platform_device;
- result = sysfs_create_group(&ideapad_priv->platform_device->dev.kobj,
+ result = sysfs_create_group(&priv->platform_device->dev.kobj,
&ideapad_attribute_group);
if (result)
goto fail_sysfs;
return 0;
fail_sysfs:
- platform_device_del(ideapad_priv->platform_device);
+ platform_device_del(priv->platform_device);
fail_platform_device:
- platform_device_put(ideapad_priv->platform_device);
+ platform_device_put(priv->platform_device);
return result;
}
-static void ideapad_platform_exit(void)
+static void ideapad_platform_exit(struct ideapad_private *priv)
{
- sysfs_remove_group(&ideapad_priv->platform_device->dev.kobj,
+ sysfs_remove_group(&priv->platform_device->dev.kobj,
&ideapad_attribute_group);
- platform_device_unregister(ideapad_priv->platform_device);
+ platform_device_unregister(priv->platform_device);
}
/*
@@ -343,7 +343,7 @@ static const struct key_entry ideapad_keymap[] = {
{ KE_END, 0 },
};
-static int __devinit ideapad_input_init(void)
+static int __devinit ideapad_input_init(struct ideapad_private *priv)
{
struct input_dev *inputdev;
int error;
@@ -357,7 +357,7 @@ static int __devinit ideapad_input_init(void)
inputdev->name = "Ideapad extra buttons";
inputdev->phys = "ideapad/input0";
inputdev->id.bustype = BUS_HOST;
- inputdev->dev.parent = &ideapad_priv->platform_device->dev;
+ inputdev->dev.parent = &priv->platform_device->dev;
error = sparse_keymap_setup(inputdev, ideapad_keymap, NULL);
if (error) {
@@ -371,7 +371,7 @@ static int __devinit ideapad_input_init(void)
goto err_free_keymap;
}
- ideapad_priv->inputdev = inputdev;
+ priv->inputdev = inputdev;
return 0;
err_free_keymap:
@@ -381,16 +381,17 @@ err_free_dev:
return error;
}
-static void __devexit ideapad_input_exit(void)
+static void __devexit ideapad_input_exit(struct ideapad_private *priv)
{
- sparse_keymap_free(ideapad_priv->inputdev);
- input_unregister_device(ideapad_priv->inputdev);
- ideapad_priv->inputdev = NULL;
+ sparse_keymap_free(priv->inputdev);
+ input_unregister_device(priv->inputdev);
+ priv->inputdev = NULL;
}
-static void ideapad_input_report(unsigned long scancode)
+static void ideapad_input_report(struct ideapad_private *priv,
+ unsigned long scancode)
{
- sparse_keymap_report_event(ideapad_priv->inputdev, scancode, 1, true);
+ sparse_keymap_report_event(priv->inputdev, scancode, 1, true);
}
/*
@@ -417,11 +418,11 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
priv->handle = adevice->handle;
dev_set_drvdata(&adevice->dev, priv);
- ret = ideapad_platform_init();
+ ret = ideapad_platform_init(priv);
if (ret)
goto platform_failed;
- ret = ideapad_input_init();
+ ret = ideapad_input_init(priv);
if (ret)
goto input_failed;
@@ -434,7 +435,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
return 0;
input_failed:
- ideapad_platform_exit();
+ ideapad_platform_exit(priv);
platform_failed:
kfree(priv);
return ret;
@@ -447,8 +448,8 @@ static int __devexit ideapad_acpi_remove(struct acpi_device *adevice, int type)
for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++)
ideapad_unregister_rfkill(adevice, i);
- ideapad_input_exit();
- ideapad_platform_exit();
+ ideapad_input_exit(priv);
+ ideapad_platform_exit(priv);
dev_set_drvdata(&adevice->dev, NULL);
kfree(priv);
@@ -457,6 +458,7 @@ static int __devexit ideapad_acpi_remove(struct acpi_device *adevice, int type)
static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
{
+ struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
acpi_handle handle = adevice->handle;
unsigned long vpc1, vpc2, vpc_bit;
@@ -471,7 +473,7 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
if (vpc_bit == 9)
ideapad_sync_rfk_state(adevice);
else
- ideapad_input_report(vpc_bit);
+ ideapad_input_report(priv, vpc_bit);
}
}
}
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 6/6] ideapad: pass ideapad_priv as argument (part 2)
2010-12-13 9:59 [PATCH v3 0/6] ideapad: hotkey enablement Ike Panhc
` (4 preceding siblings ...)
2010-12-13 10:01 ` [PATCH 5/6] ideapad: pass ideapad_priv as argument (part 1) Ike Panhc
@ 2010-12-13 10:01 ` Ike Panhc
2010-12-20 16:14 ` [PATCH v3 0/6] ideapad: hotkey enablement Matthew Garrett
6 siblings, 0 replies; 8+ messages in thread
From: Ike Panhc @ 2010-12-13 10:01 UTC (permalink / raw)
To: linux-kernel, platform-driver-x86, linux-acpi
Cc: Matthew Garrett, David Woodhouse, Dmitry Torokhov, Dave Hansen,
Corentin Chary
Passing ideapad_priv as argument and try not to using too much global variable.
This is part 2 for rfkill.
Signed-off-by: Ike Panhc <ike.pan@canonical.com>
---
drivers/platform/x86/ideapad-laptop.c | 71 +++++++++++++-------------------
1 files changed, 29 insertions(+), 42 deletions(-)
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 37fe0d0..114d952 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -31,32 +31,15 @@
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
-#define IDEAPAD_DEV_CAMERA 0
-#define IDEAPAD_DEV_WLAN 1
-#define IDEAPAD_DEV_BLUETOOTH 2
-#define IDEAPAD_DEV_3G 3
-#define IDEAPAD_DEV_KILLSW 4
+#define IDEAPAD_RFKILL_DEV_NUM (3)
struct ideapad_private {
- acpi_handle handle;
- struct rfkill *rfk[5];
+ struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM];
struct platform_device *platform_device;
struct input_dev *inputdev;
-} *ideapad_priv;
-
-static struct {
- char *name;
- int cfgbit;
- int opcode;
- int type;
-} ideapad_rfk_data[] = {
- { "ideapad_camera", 19, 0x1E, NUM_RFKILL_TYPES },
- { "ideapad_wlan", 18, 0x15, RFKILL_TYPE_WLAN },
- { "ideapad_bluetooth", 16, 0x17, RFKILL_TYPE_BLUETOOTH },
- { "ideapad_3g", 17, 0x20, RFKILL_TYPE_WWAN },
- { "ideapad_killsw", 0, 0, RFKILL_TYPE_WLAN }
};
+static acpi_handle ideapad_handle;
static bool no_bt_rfkill;
module_param(no_bt_rfkill, bool, 0444);
MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth.");
@@ -176,11 +159,9 @@ static ssize_t show_ideapad_cam(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- struct ideapad_private *priv = dev_get_drvdata(dev);
- acpi_handle handle = priv->handle;
unsigned long result;
- if (read_ec_data(handle, 0x1D, &result))
+ if (read_ec_data(ideapad_handle, 0x1D, &result))
return sprintf(buf, "-1\n");
return sprintf(buf, "%lu\n", result);
}
@@ -189,15 +170,13 @@ static ssize_t store_ideapad_cam(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct ideapad_private *priv = dev_get_drvdata(dev);
- acpi_handle handle = priv->handle;
int ret, state;
if (!count)
return 0;
if (sscanf(buf, "%i", &state) != 1)
return -EINVAL;
- ret = write_ec_cmd(handle, 0x1E, state);
+ ret = write_ec_cmd(ideapad_handle, 0x1E, state);
if (ret < 0)
return ret;
return count;
@@ -208,16 +187,24 @@ static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam);
/*
* Rfkill
*/
+struct ideapad_rfk_data {
+ char *name;
+ int cfgbit;
+ int opcode;
+ int type;
+};
+
+const struct ideapad_rfk_data ideapad_rfk_data[] = {
+ { "ideapad_wlan", 18, 0x15, RFKILL_TYPE_WLAN },
+ { "ideapad_bluetooth", 16, 0x17, RFKILL_TYPE_BLUETOOTH },
+ { "ideapad_3g", 17, 0x20, RFKILL_TYPE_WWAN },
+};
+
static int ideapad_rfk_set(void *data, bool blocked)
{
- int device = (unsigned long)data;
-
- if (device == IDEAPAD_DEV_KILLSW)
- return -EINVAL;
+ unsigned long opcode = (unsigned long)data;
- return write_ec_cmd(ideapad_priv->handle,
- ideapad_rfk_data[device].opcode,
- !blocked);
+ return write_ec_cmd(ideapad_handle, opcode, !blocked);
}
static struct rfkill_ops ideapad_rfk_ops = {
@@ -227,15 +214,14 @@ static struct rfkill_ops ideapad_rfk_ops = {
static void ideapad_sync_rfk_state(struct acpi_device *adevice)
{
struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
- acpi_handle handle = priv->handle;
unsigned long hw_blocked;
int i;
- if (read_ec_data(handle, 0x23, &hw_blocked))
+ if (read_ec_data(ideapad_handle, 0x23, &hw_blocked))
return;
hw_blocked = !hw_blocked;
- for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++)
+ for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++)
if (priv->rfk[i])
rfkill_set_hw_state(priv->rfk[i], hw_blocked);
}
@@ -250,7 +236,7 @@ static int __devinit ideapad_register_rfkill(struct acpi_device *adevice,
if (no_bt_rfkill &&
(ideapad_rfk_data[dev].type == RFKILL_TYPE_BLUETOOTH)) {
/* Force to enable bluetooth when no_bt_rfkill=1 */
- write_ec_cmd(ideapad_priv->handle,
+ write_ec_cmd(ideapad_handle,
ideapad_rfk_data[dev].opcode, 1);
return 0;
}
@@ -261,7 +247,7 @@ static int __devinit ideapad_register_rfkill(struct acpi_device *adevice,
if (!priv->rfk[dev])
return -ENOMEM;
- if (read_ec_data(ideapad_priv->handle, ideapad_rfk_data[dev].opcode-1,
+ if (read_ec_data(ideapad_handle, ideapad_rfk_data[dev].opcode-1,
&sw_blocked)) {
rfkill_init_sw_state(priv->rfk[dev], 0);
} else {
@@ -414,9 +400,8 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- ideapad_priv = priv;
- priv->handle = adevice->handle;
dev_set_drvdata(&adevice->dev, priv);
+ ideapad_handle = adevice->handle;
ret = ideapad_platform_init(priv);
if (ret)
@@ -426,9 +411,11 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice)
if (ret)
goto input_failed;
- for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++) {
+ for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) {
if (test_bit(ideapad_rfk_data[i].cfgbit, (unsigned long *)&cfg))
ideapad_register_rfkill(adevice, i);
+ else
+ priv->rfk[i] = NULL;
}
ideapad_sync_rfk_state(adevice);
@@ -446,7 +433,7 @@ static int __devexit ideapad_acpi_remove(struct acpi_device *adevice, int type)
struct ideapad_private *priv = dev_get_drvdata(&adevice->dev);
int i;
- for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++)
+ for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++)
ideapad_unregister_rfkill(adevice, i);
ideapad_input_exit(priv);
ideapad_platform_exit(priv);
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v3 0/6] ideapad: hotkey enablement
2010-12-13 9:59 [PATCH v3 0/6] ideapad: hotkey enablement Ike Panhc
` (5 preceding siblings ...)
2010-12-13 10:01 ` [PATCH 6/6] ideapad: pass ideapad_priv as argument (part 2) Ike Panhc
@ 2010-12-20 16:14 ` Matthew Garrett
6 siblings, 0 replies; 8+ messages in thread
From: Matthew Garrett @ 2010-12-20 16:14 UTC (permalink / raw)
To: Ike Panhc
Cc: linux-kernel, platform-driver-x86, linux-acpi, David Woodhouse,
Dmitry Torokhov, Dave Hansen, Corentin Chary
On Mon, Dec 13, 2010 at 05:59:44PM +0800, Ike Panhc wrote:
> Here are the enablement patches for hotkey events on ideapads and these patches
> are made against current checkout of mainline kernel.
>
> After last time posting on LKML, there are several feedback and these patches
> are modified.
Thanks, merged in -next.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 8+ messages in thread