aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-01-21 14:56:44 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2010-01-21 14:56:44 -0800
commit878d42113b5c7c1cb7c3e3b909e68f5942604c99 (patch)
tree1f35b1647aad924814095510a606545878c51868
parent86428976d9e12f3900a60946acf4d9a42e4b20ea (diff)
downloadpatches-878d42113b5c7c1cb7c3e3b909e68f5942604c99.tar.gz
a msi and usb patch
-rw-r--r--driver-core/msi-laptop-support-some-msi-3g-netbook-that-is-need-load-scm.patch340
-rw-r--r--series2
-rw-r--r--usb/usb-remove-the-berry_charge-driver.patch236
3 files changed, 578 insertions, 0 deletions
diff --git a/driver-core/msi-laptop-support-some-msi-3g-netbook-that-is-need-load-scm.patch b/driver-core/msi-laptop-support-some-msi-3g-netbook-that-is-need-load-scm.patch
new file mode 100644
index 00000000000000..ef50862ef737b4
--- /dev/null
+++ b/driver-core/msi-laptop-support-some-msi-3g-netbook-that-is-need-load-scm.patch
@@ -0,0 +1,340 @@
+From eb7fa79aaab66b15257a1d10fccd5a526919b193 Mon Sep 17 00:00:00 2001
+From: Lee, Chun-Yi <jlee@novell.com>
+Date: Fri, 22 Jan 2010 00:15:59 +0800
+Subject: msi-laptop: Support some MSI 3G netbook that is need load SCM
+
+Some MSI 3G netbook only have one fn key to control Wlan/Bluetooth/3G,
+those netbook will load the SCM (windows app) to disable the original
+Wlan/Bluetooth control by BIOS when user press fn key, then control
+Wlan/Bluetooth/3G by SCM (software control by OS). Without SCM, user
+cann't on/off 3G module on those 3G netbook.
+On Linux, msi-laptop driver will do the same thing to disable the
+original BIOS control, then might need use HAL or other userland
+application to do the software control that simulate with SCM.
+e.g. MSI N034 netbook
+
+Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
+Cc: Lennart Poettering <mzxreary@0pointer.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/platform/x86/msi-laptop.c | 238 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 238 insertions(+)
+
+--- a/drivers/platform/x86/msi-laptop.c
++++ b/drivers/platform/x86/msi-laptop.c
+@@ -58,6 +58,7 @@
+ #include <linux/dmi.h>
+ #include <linux/backlight.h>
+ #include <linux/platform_device.h>
++#include <linux/rfkill.h>
+
+ #define MSI_DRIVER_VERSION "0.5"
+
+@@ -72,6 +73,10 @@
+ #define MSI_STANDARD_EC_WLAN_MASK (1 << 3)
+ #define MSI_STANDARD_EC_3G_MASK (1 << 4)
+
++/* For set SCM load flag to disable BIOS fn key */
++#define MSI_STANDARD_EC_SCM_LOAD_ADDRESS 0x2d
++#define MSI_STANDARD_EC_SCM_LOAD_MASK (1 << 0)
++
+ static int force;
+ module_param(force, bool, 0);
+ MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
+@@ -83,6 +88,19 @@ MODULE_PARM_DESC(auto_brightness, "Enabl
+ static bool old_ec_model;
+ static int wlan_s, bluetooth_s, threeg_s;
+
++/* Some MSI 3G netbook only have one fn key to control Wlan/Bluetooth/3G,
++ * those netbook will load the SCM (windows app) to disable the original
++ * Wlan/Bluetooth control by BIOS when user press fn key, then control
++ * Wlan/Bluetooth/3G by SCM (software control by OS). Without SCM, user
++ * cann't on/off 3G module on those 3G netbook.
++ * On Linux, msi-laptop driver will do the same thing to disable the
++ * original BIOS control, then might need use HAL or other userland
++ * application to do the software control that simulate with SCM.
++ * e.g. MSI N034 netbook
++ */
++static bool load_scm_model;
++static struct rfkill *rfk_wlan, *rfk_bluetooth, *rfk_threeg;
++
+ /* Hardware access */
+
+ static int set_lcd_level(int level)
+@@ -139,6 +157,35 @@ static int set_auto_brightness(int enabl
+ return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0, 1);
+ }
+
++static ssize_t set_device_state(const char *buf, size_t count, u8 mask)
++{
++ int status;
++ u8 wdata = 0, rdata;
++ int result;
++
++ if (sscanf(buf, "%i", &status) != 1 || (status < 0 || status > 1))
++ return -EINVAL;
++
++ /* read current device state */
++ result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata);
++ if (result < 0)
++ return -EINVAL;
++
++ if (!!(rdata & mask) != status) {
++ /* reverse device bit */
++ if (rdata & mask)
++ wdata = rdata & ~mask;
++ else
++ wdata = rdata | mask;
++
++ result = ec_write(MSI_STANDARD_EC_COMMAND_ADDRESS, wdata);
++ if (result < 0)
++ return -EINVAL;
++ }
++
++ return count;
++}
++
+ static int get_wireless_state(int *wlan, int *bluetooth)
+ {
+ u8 wdata = 0, rdata;
+@@ -215,6 +262,12 @@ static ssize_t show_wlan(struct device *
+ return sprintf(buf, "%i\n", enabled);
+ }
+
++static ssize_t store_wlan(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ return set_device_state(buf, count, MSI_STANDARD_EC_WLAN_MASK);
++}
++
+ static ssize_t show_bluetooth(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+@@ -233,6 +286,12 @@ static ssize_t show_bluetooth(struct dev
+ return sprintf(buf, "%i\n", enabled);
+ }
+
++static ssize_t store_bluetooth(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ return set_device_state(buf, count, MSI_STANDARD_EC_BLUETOOTH_MASK);
++}
++
+ static ssize_t show_threeg(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+@@ -250,6 +309,12 @@ static ssize_t show_threeg(struct device
+ return sprintf(buf, "%i\n", threeg_s);
+ }
+
++static ssize_t store_threeg(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ return set_device_state(buf, count, MSI_STANDARD_EC_3G_MASK);
++}
++
+ static ssize_t show_lcd_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+@@ -387,6 +452,169 @@ static struct dmi_system_id __initdata m
+ { }
+ };
+
++static struct dmi_system_id __initdata msi_load_scm_models_dmi_table[] = {
++ {
++ .ident = "MSI N034",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR,
++ "MICRO-STAR INTERNATIONAL CO., LTD"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "MS-N034"),
++ DMI_MATCH(DMI_CHASSIS_VENDOR,
++ "MICRO-STAR INTERNATIONAL CO., LTD")
++ },
++ .callback = dmi_check_cb
++ },
++ { }
++};
++
++static int rfkill_bluetooth_set(void *data, bool blocked)
++{
++ /* Do something with blocked...*/
++ /*
++ * blocked == false is on
++ * blocked == true is off
++ */
++ if (blocked)
++ set_device_state("0", 0, MSI_STANDARD_EC_BLUETOOTH_MASK);
++ else
++ set_device_state("1", 0, MSI_STANDARD_EC_BLUETOOTH_MASK);
++
++ return 0;
++}
++
++static int rfkill_wlan_set(void *data, bool blocked)
++{
++ if (blocked)
++ set_device_state("0", 0, MSI_STANDARD_EC_WLAN_MASK);
++ else
++ set_device_state("1", 0, MSI_STANDARD_EC_WLAN_MASK);
++
++ return 0;
++}
++
++static int rfkill_threeg_set(void *data, bool blocked)
++{
++ if (blocked)
++ set_device_state("0", 0, MSI_STANDARD_EC_3G_MASK);
++ else
++ set_device_state("1", 0, MSI_STANDARD_EC_3G_MASK);
++
++ return 0;
++}
++
++static struct rfkill_ops rfkill_bluetooth_ops = {
++ .set_block = rfkill_bluetooth_set
++};
++
++static struct rfkill_ops rfkill_wlan_ops = {
++ .set_block = rfkill_wlan_set
++};
++
++static struct rfkill_ops rfkill_threeg_ops = {
++ .set_block = rfkill_threeg_set
++};
++
++static void rfkill_cleanup(void)
++{
++ if (rfk_bluetooth) {
++ rfkill_unregister(rfk_bluetooth);
++ rfkill_destroy(rfk_bluetooth);
++ }
++
++ if (rfk_threeg) {
++ rfkill_unregister(rfk_threeg);
++ rfkill_destroy(rfk_threeg);
++ }
++
++ if (rfk_wlan) {
++ rfkill_unregister(rfk_wlan);
++ rfkill_destroy(rfk_wlan);
++ }
++}
++
++static int rfkill_init(struct platform_device *sdev)
++{
++ /* add rfkill */
++ int retval;
++
++ rfk_bluetooth = rfkill_alloc("msi-bluetooth", &sdev->dev,
++ RFKILL_TYPE_BLUETOOTH,
++ &rfkill_bluetooth_ops, NULL);
++ if (!rfk_bluetooth) {
++ retval = -ENOMEM;
++ goto err_bluetooth;
++ }
++ retval = rfkill_register(rfk_bluetooth);
++ if (retval)
++ goto err_bluetooth;
++
++ rfk_wlan = rfkill_alloc("msi-wlan", &sdev->dev, RFKILL_TYPE_WLAN,
++ &rfkill_wlan_ops, NULL);
++ if (!rfk_wlan) {
++ retval = -ENOMEM;
++ goto err_wlan;
++ }
++ retval = rfkill_register(rfk_wlan);
++ if (retval)
++ goto err_wlan;
++
++ rfk_threeg = rfkill_alloc("msi-threeg", &sdev->dev, RFKILL_TYPE_WWAN,
++ &rfkill_threeg_ops, NULL);
++ if (!rfk_threeg) {
++ retval = -ENOMEM;
++ goto err_threeg;
++ }
++ retval = rfkill_register(rfk_threeg);
++ if (retval)
++ goto err_threeg;
++
++ return 0;
++
++err_threeg:
++ rfkill_destroy(rfk_threeg);
++ if (rfk_wlan)
++ rfkill_unregister(rfk_wlan);
++err_wlan:
++ rfkill_destroy(rfk_wlan);
++ if (rfk_bluetooth)
++ rfkill_unregister(rfk_bluetooth);
++err_bluetooth:
++ rfkill_destroy(rfk_bluetooth);
++
++ return retval;
++}
++
++static int load_scm_model_init(struct platform_device *sdev)
++{
++ u8 data;
++ int result;
++
++ /* allow userland write sysfs file */
++ dev_attr_bluetooth.store = store_bluetooth;
++ dev_attr_wlan.store = store_wlan;
++ dev_attr_threeg.store = store_threeg;
++ dev_attr_bluetooth.attr.mode |= S_IWUSR;
++ dev_attr_wlan.attr.mode |= S_IWUSR;
++ dev_attr_threeg.attr.mode |= S_IWUSR;
++
++ /* disable hardware control by fn key */
++ result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data);
++ if (result < 0)
++ return result;
++
++ result = ec_write(MSI_STANDARD_EC_SCM_LOAD_ADDRESS,
++ data | MSI_STANDARD_EC_SCM_LOAD_MASK);
++ if (result < 0)
++ return result;
++
++ /* initial rfkill */
++ result = rfkill_init(sdev);
++ if (result < 0)
++ return result;
++
++ return 0;
++}
++
+ static int __init msi_init(void)
+ {
+ int ret;
+@@ -397,6 +625,9 @@ static int __init msi_init(void)
+ if (force || dmi_check_system(msi_dmi_table))
+ old_ec_model = 1;
+
++ if (!old_ec_model && dmi_check_system(msi_load_scm_models_dmi_table))
++ load_scm_model = 1;
++
+ if (auto_brightness < 0 || auto_brightness > 2)
+ return -EINVAL;
+
+@@ -429,6 +660,11 @@ static int __init msi_init(void)
+ if (ret)
+ goto fail_platform_device1;
+
++ if (load_scm_model && (load_scm_model_init(msipf_device) < 0)) {
++ ret = -EINVAL;
++ goto fail_platform_device1;
++ }
++
+ ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group);
+ if (ret)
+ goto fail_platform_device2;
+@@ -479,6 +715,8 @@ static void __exit msi_cleanup(void)
+ platform_driver_unregister(&msipf_driver);
+ backlight_device_unregister(msibl_device);
+
++ rfkill_cleanup();
++
+ /* Enable automatic brightness control again */
+ if (auto_brightness != 2)
+ set_auto_brightness(1);
diff --git a/series b/series
index b6c0c6c69861e3..ca558580691867 100644
--- a/series
+++ b/series
@@ -58,6 +58,7 @@ driver-core/howto-updates-on-subsystem-trees-patchwork-next-vs.-mm.patch
# sent to Lennart 01-15-2010
driver-core/msi-laptop-support-standard-ec-66-62-command-on-msi-notebook-and-nebook.patch
driver-core/msi-laptop-add-threeg-sysfs-file-for-support-query-3g-state-by-standard-66-62-ec-command.patch
+driver-core/msi-laptop-support-some-msi-3g-netbook-that-is-need-load-scm.patch
#####################################
# TTY patches for after 2.6.33 is out
@@ -236,6 +237,7 @@ usb/usb-bkl-removal-legousbtower.patch
usb/usb-bkl-removal-vstusb.patch
usb/usb-bkl-removal-frontier.patch
usb/usb-bkl-removal-from-ioctl-path-of-usbfs.patch
+usb/usb-remove-the-berry_charge-driver.patch
diff --git a/usb/usb-remove-the-berry_charge-driver.patch b/usb/usb-remove-the-berry_charge-driver.patch
new file mode 100644
index 00000000000000..d054779425459c
--- /dev/null
+++ b/usb/usb-remove-the-berry_charge-driver.patch
@@ -0,0 +1,236 @@
+From foo@baz Thu Jan 21 14:54:10 PST 2010
+Date: Thu, 21 Jan 2010 14:54:10 -0800
+To: Greg KH <greg@kroah.com>
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: USB: remove the berry_charge driver
+
+The Barry project's userspace program, bcharge, can better handle this
+device and functionality, and it also works with the latest phones,
+which this driver does not support. So remove it, as the userspace code
+should be used instead.
+
+Cc: Chris Frey <cdfrey@foursquare.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/misc/Kconfig | 11 --
+ drivers/usb/misc/Makefile | 1
+ drivers/usb/misc/berry_charge.c | 183 ----------------------------------------
+ 3 files changed, 195 deletions(-)
+
+--- a/drivers/usb/misc/berry_charge.c
++++ /dev/null
+@@ -1,183 +0,0 @@
+-/*
+- * USB BlackBerry charging module
+- *
+- * Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de>
+- *
+- * 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, version 2.
+- *
+- * Information on how to switch configs was taken by the bcharge.cc file
+- * created by the barry.sf.net project.
+- *
+- * bcharge.cc has the following copyright:
+- * Copyright (C) 2006, Net Direct Inc. (http://www.netdirect.ca/)
+- * and is released under the GPLv2.
+- *
+- *
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/errno.h>
+-#include <linux/init.h>
+-#include <linux/slab.h>
+-#include <linux/module.h>
+-#include <linux/usb.h>
+-
+-#define RIM_VENDOR 0x0fca
+-#define BLACKBERRY 0x0001
+-#define BLACKBERRY_PEARL_DUAL 0x0004
+-#define BLACKBERRY_PEARL 0x0006
+-
+-static int debug;
+-static int pearl_dual_mode = 1;
+-
+-#ifdef dbg
+-#undef dbg
+-#endif
+-#define dbg(dev, format, arg...) \
+- if (debug) \
+- dev_printk(KERN_DEBUG , dev , format , ## arg)
+-
+-static const struct usb_device_id id_table[] = {
+- { USB_DEVICE(RIM_VENDOR, BLACKBERRY) },
+- { USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL) },
+- { USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL_DUAL) },
+- { }, /* Terminating entry */
+-};
+-MODULE_DEVICE_TABLE(usb, id_table);
+-
+-static int magic_charge(struct usb_device *udev)
+-{
+- char *dummy_buffer = kzalloc(2, GFP_KERNEL);
+- int retval;
+-
+- if (!dummy_buffer)
+- return -ENOMEM;
+-
+- /* send two magic commands and then set the configuration. The device
+- * will then reset itself with the new power usage and should start
+- * charging. */
+-
+- /* Note, with testing, it only seems that the first message is really
+- * needed (at least for the 8700c), but to be safe, we emulate what
+- * other operating systems seem to be sending to their device. We
+- * really need to get some specs for this device to be sure about what
+- * is going on here.
+- */
+- dbg(&udev->dev, "Sending first magic command\n");
+- retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+- 0xa5, 0xc0, 0, 1, dummy_buffer, 2, 100);
+- if (retval != 2) {
+- dev_err(&udev->dev, "First magic command failed: %d.\n",
+- retval);
+- goto exit;
+- }
+-
+- dbg(&udev->dev, "Sending second magic command\n");
+- retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+- 0xa2, 0x40, 0, 1, dummy_buffer, 0, 100);
+- if (retval != 0) {
+- dev_err(&udev->dev, "Second magic command failed: %d.\n",
+- retval);
+- goto exit;
+- }
+-
+- dbg(&udev->dev, "Calling set_configuration\n");
+- retval = usb_driver_set_configuration(udev, 1);
+- if (retval)
+- dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
+-
+-exit:
+- kfree(dummy_buffer);
+- return retval;
+-}
+-
+-static int magic_dual_mode(struct usb_device *udev)
+-{
+- char *dummy_buffer = kzalloc(2, GFP_KERNEL);
+- int retval;
+-
+- if (!dummy_buffer)
+- return -ENOMEM;
+-
+- /* send magic command so that the Blackberry Pearl device exposes
+- * two interfaces: both the USB mass-storage one and one which can
+- * be used for database access. */
+- dbg(&udev->dev, "Sending magic pearl command\n");
+- retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+- 0xa9, 0xc0, 1, 1, dummy_buffer, 2, 100);
+- dbg(&udev->dev, "Magic pearl command returned %d\n", retval);
+-
+- dbg(&udev->dev, "Calling set_configuration\n");
+- retval = usb_driver_set_configuration(udev, 1);
+- if (retval)
+- dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
+-
+- kfree(dummy_buffer);
+- return retval;
+-}
+-
+-static int berry_probe(struct usb_interface *intf,
+- const struct usb_device_id *id)
+-{
+- struct usb_device *udev = interface_to_usbdev(intf);
+-
+- if (udev->bus_mA < 500) {
+- dbg(&udev->dev, "Not enough power to charge available\n");
+- return -ENODEV;
+- }
+-
+- dbg(&udev->dev, "Power is set to %dmA\n",
+- udev->actconfig->desc.bMaxPower * 2);
+-
+- /* check the power usage so we don't try to enable something that is
+- * already enabled */
+- if ((udev->actconfig->desc.bMaxPower * 2) == 500) {
+- dbg(&udev->dev, "device is already charging, power is "
+- "set to %dmA\n", udev->actconfig->desc.bMaxPower * 2);
+- return -ENODEV;
+- }
+-
+- /* turn the power on */
+- magic_charge(udev);
+-
+- if ((le16_to_cpu(udev->descriptor.idProduct) == BLACKBERRY_PEARL) &&
+- (pearl_dual_mode))
+- magic_dual_mode(udev);
+-
+- /* we don't really want to bind to the device, userspace programs can
+- * handle the syncing just fine, so get outta here. */
+- return -ENODEV;
+-}
+-
+-static void berry_disconnect(struct usb_interface *intf)
+-{
+-}
+-
+-static struct usb_driver berry_driver = {
+- .name = "berry_charge",
+- .probe = berry_probe,
+- .disconnect = berry_disconnect,
+- .id_table = id_table,
+-};
+-
+-static int __init berry_init(void)
+-{
+- return usb_register(&berry_driver);
+-}
+-
+-static void __exit berry_exit(void)
+-{
+- usb_deregister(&berry_driver);
+-}
+-
+-module_init(berry_init);
+-module_exit(berry_exit);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
+-module_param(debug, bool, S_IRUGO | S_IWUSR);
+-MODULE_PARM_DESC(debug, "Debug enabled or not");
+-module_param(pearl_dual_mode, bool, S_IRUGO | S_IWUSR);
+-MODULE_PARM_DESC(pearl_dual_mode, "Change Blackberry Pearl to run in dual mode");
+--- a/drivers/usb/misc/Kconfig
++++ b/drivers/usb/misc/Kconfig
+@@ -87,17 +87,6 @@ config USB_LCD
+ To compile this driver as a module, choose M here: the
+ module will be called usblcd.
+
+-config USB_BERRY_CHARGE
+- tristate "USB BlackBerry recharge support"
+- depends on USB
+- help
+- Say Y here if you want to connect a BlackBerry device to your
+- computer's USB port and have it automatically switch to "recharge"
+- mode.
+-
+- To compile this driver as a module, choose M here: the
+- module will be called berry_charge.
+-
+ config USB_LED
+ tristate "USB LED driver support"
+ depends on USB
+--- a/drivers/usb/misc/Makefile
++++ b/drivers/usb/misc/Makefile
+@@ -5,7 +5,6 @@
+
+ obj-$(CONFIG_USB_ADUTUX) += adutux.o
+ obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o
+-obj-$(CONFIG_USB_BERRY_CHARGE) += berry_charge.o
+ obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
+ obj-$(CONFIG_USB_CYTHERM) += cytherm.o
+ obj-$(CONFIG_USB_EMI26) += emi26.o