From b575a2349eefc6ff59b9beff14ca9e0d58f2ab65 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 13 Nov 2011 19:14:22 +0000 Subject: [PATCH] [x86] Add amilo-rfkill driver for some Fujitsu-Siemens Amilo laptops (Closes: #631664) svn path=/dists/trunk/linux-2.6/; revision=18263 --- debian/changelog | 2 + debian/config/kernelarch-x86/config | 1 + ...kill-driver-for-some-Fujitsu-Siemens.patch | 241 ++++++++++++++++++ debian/patches/series/base | 1 + 4 files changed, 245 insertions(+) create mode 100644 debian/patches/features/x86/x86-Add-amilo-rfkill-driver-for-some-Fujitsu-Siemens.patch diff --git a/debian/changelog b/debian/changelog index 37ebddaff..82ce53df2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -22,6 +22,8 @@ linux-2.6 (3.1.1-1) UNRELEASED; urgency=low * vmscan: fix shrinker callback bug in fs/super.c * [ia64] Add accept4() syscall, thanks to Émeric Maschino (Closes: #647825) * block: Always check length of all iov entries in blk_rq_map_user_iov() + * [x86] Add amilo-rfkill driver for some Fujitsu-Siemens Amilo laptops + (Closes: #631664) -- Ben Hutchings Fri, 04 Nov 2011 15:05:47 +0000 diff --git a/debian/config/kernelarch-x86/config b/debian/config/kernelarch-x86/config index 74ea5cb22..8101e4c04 100644 --- a/debian/config/kernelarch-x86/config +++ b/debian/config/kernelarch-x86/config @@ -981,6 +981,7 @@ CONFIG_ACERHDF=m CONFIG_DELL_LAPTOP=m CONFIG_DELL_WMI=m CONFIG_DELL_WMI_AIO=m +CONFIG_AMILO_RFKILL=m CONFIG_HP_ACCEL=m CONFIG_SONYPI_COMPAT=y CONFIG_IDEAPAD_LAPTOP=m diff --git a/debian/patches/features/x86/x86-Add-amilo-rfkill-driver-for-some-Fujitsu-Siemens.patch b/debian/patches/features/x86/x86-Add-amilo-rfkill-driver-for-some-Fujitsu-Siemens.patch new file mode 100644 index 000000000..614a4fd89 --- /dev/null +++ b/debian/patches/features/x86/x86-Add-amilo-rfkill-driver-for-some-Fujitsu-Siemens.patch @@ -0,0 +1,241 @@ +From: Ben Hutchings +Date: Mon, 17 Oct 2011 04:13:27 +0100 +Subject: [PATCH] x86: Add amilo-rfkill driver for some Fujitsu-Siemens Amilo + laptops + +An rfkill driver based on the fsaa1655g and fsam7440 drivers for +Fujitsu-Siemens Amilo A1655 and M7440 models found at: + +http://sourceforge.net/projects/fsaa1655g/ +http://sourceforge.net/projects/fsam7440/ + +This adds DMI matching and replaces the procfs files with rfkill +devices. + +Signed-off-by: Ben Hutchings +--- + drivers/platform/x86/Kconfig | 7 ++ + drivers/platform/x86/Makefile | 1 + + drivers/platform/x86/amilo-rfkill.c | 180 +++++++++++++++++++++++++++++++++++ + 3 files changed, 188 insertions(+), 0 deletions(-) + create mode 100644 drivers/platform/x86/amilo-rfkill.c + +diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig +index 7f43cf8..cb2c255 100644 +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -143,6 +143,13 @@ config FUJITSU_LAPTOP_DEBUG + + If you are not sure, say N here. + ++config AMILO_RFKILL ++ tristate "Fujitsu-Siemens Amilo rfkill support" ++ depends on RFKILL ++ ---help--- ++ This is a driver for enabling wifi on some Fujitsu-Siemens Amilo ++ laptops. ++ + config TC1100_WMI + tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)" + depends on !X86_64 +diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile +index 293a320..3acbaad 100644 +--- a/drivers/platform/x86/Makefile ++++ b/drivers/platform/x86/Makefile +@@ -17,6 +17,7 @@ obj-$(CONFIG_ACER_WMI) += acer-wmi.o + obj-$(CONFIG_ACERHDF) += acerhdf.o + obj-$(CONFIG_HP_ACCEL) += hp_accel.o + obj-$(CONFIG_HP_WMI) += hp-wmi.o ++obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o + obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o + obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o + obj-$(CONFIG_IDEAPAD_LAPTOP) += ideapad-laptop.o +diff --git a/drivers/platform/x86/amilo-rfkill.c b/drivers/platform/x86/amilo-rfkill.c +new file mode 100644 +index 0000000..028d3ec +--- /dev/null ++++ b/drivers/platform/x86/amilo-rfkill.c +@@ -0,0 +1,180 @@ ++/* ++ * Support for rfkill on some Fujitsu-Siemens Amilo laptops. ++ * Copyright 2011 Ben Hutchings. ++ * ++ * Based in part on the fsam7440 driver, which is: ++ * Copyright 2005 Alejandro Vidal Mata & Javier Vidal Mata. ++ * and on the fsaa1655g driver, which is: ++ * Copyright 2006 Martin Večeřa. ++ * ++ * 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * These values were obtained from disassembling and debugging the ++ * PM.exe program installed in the Fujitsu-Siemens AMILO A1655G ++ */ ++#define A1655_STATE_PORT 0x64 ++#define A1655_COMMAND_PORT 0x64 ++#define A1655_DATA_PORT 0x60 ++#define A1655_WIFI_COMMAND 0xC5 ++#define A1655_WIFI_ON 0x25 ++#define A1655_WIFI_OFF 0x45 ++ ++static int amilo_a1655_rfkill_set_block(void *data, bool blocked) ++{ ++ u8 val; ++ ++ do ++ val = inb(A1655_STATE_PORT); ++ while ((val & 2) == 2); ++ outb(A1655_WIFI_COMMAND, A1655_COMMAND_PORT); ++ do ++ val = inb(A1655_STATE_PORT); ++ while ((val & 2) == 2); ++ outb(blocked ? A1655_WIFI_OFF : A1655_WIFI_ON, A1655_DATA_PORT); ++ ++ return 0; ++} ++ ++static const struct rfkill_ops amilo_a1655_rfkill_ops = { ++ .set_block = amilo_a1655_rfkill_set_block ++}; ++ ++/* ++ * These values were obtained from disassembling the PM.exe program ++ * installed in the Fujitsu-Siemens AMILO M 7440 ++ */ ++#define M7440_PORT1 0x118f ++#define M7440_PORT2 0x118e ++#define M7440_RADIO_ON1 0x12 ++#define M7440_RADIO_ON2 0x80 ++#define M7440_RADIO_OFF1 0x10 ++#define M7440_RADIO_OFF2 0x00 ++ ++static int amilo_m7440_rfkill_set_block(void *data, bool blocked) ++{ ++ u8 val1 = blocked ? M7440_RADIO_OFF1 : M7440_RADIO_ON1; ++ u8 val2 = blocked ? M7440_RADIO_OFF2 : M7440_RADIO_ON2; ++ ++ outb(val1, M7440_PORT1); ++ outb(val2, M7440_PORT2); ++ ++ /* Check whether the state has changed correctly */ ++ if (inb(M7440_PORT1) != val1 || inb(M7440_PORT2) != val2) ++ return -EIO; ++ ++ return 0; ++} ++ ++static const struct rfkill_ops amilo_m7440_rfkill_ops = { ++ .set_block = amilo_m7440_rfkill_set_block ++}; ++ ++static const struct dmi_system_id __devinitdata amilo_rfkill_id_table[] = { ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), ++ DMI_MATCH(DMI_BOARD_NAME, "AMILO A1655"), ++ }, ++ .driver_data = (void *)&amilo_a1655_rfkill_ops ++ }, ++ { ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), ++ DMI_MATCH(DMI_BOARD_NAME, "AMILO M7440"), ++ }, ++ .driver_data = (void *)&amilo_m7440_rfkill_ops ++ }, ++ {} ++}; ++ ++static struct platform_device *amilo_rfkill_pdev; ++static struct rfkill *amilo_rfkill_dev; ++ ++static int __devinit amilo_rfkill_probe(struct platform_device *device) ++{ ++ const struct dmi_system_id *system_id = ++ dmi_first_match(amilo_rfkill_id_table); ++ int rc; ++ ++ amilo_rfkill_dev = rfkill_alloc(KBUILD_MODNAME, &device->dev, ++ RFKILL_TYPE_WLAN, ++ system_id->driver_data, NULL); ++ if (!amilo_rfkill_dev) ++ return -ENOMEM; ++ ++ rc = rfkill_register(amilo_rfkill_dev); ++ if (rc) ++ goto fail; ++ ++ return 0; ++ ++fail: ++ rfkill_destroy(amilo_rfkill_dev); ++ return rc; ++} ++ ++static int amilo_rfkill_remove(struct platform_device *device) ++{ ++ rfkill_unregister(amilo_rfkill_dev); ++ rfkill_destroy(amilo_rfkill_dev); ++ return 0; ++} ++ ++static struct platform_driver amilo_rfkill_driver = { ++ .driver = { ++ .name = KBUILD_MODNAME, ++ .owner = THIS_MODULE, ++ }, ++ .probe = amilo_rfkill_probe, ++ .remove = amilo_rfkill_remove, ++}; ++ ++static int __init amilo_rfkill_init(void) ++{ ++ int rc; ++ ++ if (dmi_first_match(amilo_rfkill_id_table) == NULL) ++ return -ENODEV; ++ ++ rc = platform_driver_register(&amilo_rfkill_driver); ++ if (rc) ++ return rc; ++ ++ amilo_rfkill_pdev = platform_device_register_simple(KBUILD_MODNAME, -1, ++ NULL, 0); ++ if (IS_ERR(amilo_rfkill_pdev)) { ++ rc = PTR_ERR(amilo_rfkill_pdev); ++ goto fail; ++ } ++ ++ return 0; ++ ++fail: ++ platform_driver_unregister(&amilo_rfkill_driver); ++ return rc; ++} ++ ++static void __exit amilo_rfkill_exit(void) ++{ ++ platform_device_unregister(amilo_rfkill_pdev); ++ platform_driver_unregister(&amilo_rfkill_driver); ++} ++ ++MODULE_AUTHOR("Ben Hutchings "); ++MODULE_LICENSE("GPL"); ++MODULE_DEVICE_TABLE(dmi, amilo_rfkill_id_table); ++ ++module_init(amilo_rfkill_init); ++module_exit(amilo_rfkill_exit); +-- +1.7.7.2 + diff --git a/debian/patches/series/base b/debian/patches/series/base index db2129637..84e46f87a 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -59,3 +59,4 @@ + bugfix/all/vmscan-fix-shrinker-callback-bug-in-fs-super.c.patch + bugfix/ia64/ia64-Add-accept4-syscall.patch + bugfix/all/block-Always-check-length-of-all-iov-entries-in-blk_.patch ++ features/x86/x86-Add-amilo-rfkill-driver-for-some-Fujitsu-Siemens.patch