Merge branch 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86
Pull x86 platform driver updates from Matthew Garrett: "Some significant improvements for the Sony driver on newer machines, but other than that mostly just minor fixes and a patch to remove the broken rfkill code from the Dell driver." * 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86: (35 commits) apple-gmux: Fix up the suspend/resume patch dell-laptop: Remove rfkill code toshiba_acpi: Fix mis-merge dell-laptop: Add touchpad led support for Dell V3450 acer-wmi: add 3 laptops to video backlight vendor mode quirk table sony-laptop: add touchpad enable/disable function sony-laptop: add missing Fn key combos for 0x100 handlers sony-laptop: add support for more WWAN modems sony-laptop: new keyboard backlight handle sony-laptop: add high speed battery charging function sony-laptop: support automatic resume on lid open sony-laptop: adjust error handling in finding SNC handles sony-laptop: add thermal profiles support sony-laptop: support battery care functions sony-laptop: additional debug statements sony-laptop: improve SNC initialization and acpi notify callback code sony-laptop: use kstrtoul to parse sysfs values sony-laptop: generalise ACPI calls into SNC functions sony-laptop: fix return path when no ACPI buffer is allocated sony-laptop: use soft rfkill status stored in hw ...
This commit is contained in:
commit
48445159e9
@ -523,6 +523,30 @@ static const struct dmi_system_id video_vendor_dmi_table[] = {
|
|||||||
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4750"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4750"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.callback = video_set_backlight_video_vendor,
|
||||||
|
.ident = "Acer Extensa 5235",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5235"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.callback = video_set_backlight_video_vendor,
|
||||||
|
.ident = "Acer TravelMate 5760",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5760"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.callback = video_set_backlight_video_vendor,
|
||||||
|
.ident = "Acer Aspire 5750",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,6 +87,9 @@ static int gmux_update_status(struct backlight_device *bd)
|
|||||||
struct apple_gmux_data *gmux_data = bl_get_data(bd);
|
struct apple_gmux_data *gmux_data = bl_get_data(bd);
|
||||||
u32 brightness = bd->props.brightness;
|
u32 brightness = bd->props.brightness;
|
||||||
|
|
||||||
|
if (bd->props.state & BL_CORE_SUSPENDED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Older gmux versions require writing out lower bytes first then
|
* Older gmux versions require writing out lower bytes first then
|
||||||
* setting the upper byte to 0 to flush the values. Newer versions
|
* setting the upper byte to 0 to flush the values. Newer versions
|
||||||
@ -102,6 +105,7 @@ static int gmux_update_status(struct backlight_device *bd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct backlight_ops gmux_bl_ops = {
|
static const struct backlight_ops gmux_bl_ops = {
|
||||||
|
.options = BL_CORE_SUSPENDRESUME,
|
||||||
.get_brightness = gmux_get_brightness,
|
.get_brightness = gmux_get_brightness,
|
||||||
.update_status = gmux_update_status,
|
.update_status = gmux_update_status,
|
||||||
};
|
};
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/rfkill.h>
|
|
||||||
#include <linux/power_supply.h>
|
#include <linux/power_supply.h>
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
@ -90,11 +89,8 @@ static struct platform_driver platform_driver = {
|
|||||||
|
|
||||||
static struct platform_device *platform_device;
|
static struct platform_device *platform_device;
|
||||||
static struct backlight_device *dell_backlight_device;
|
static struct backlight_device *dell_backlight_device;
|
||||||
static struct rfkill *wifi_rfkill;
|
|
||||||
static struct rfkill *bluetooth_rfkill;
|
|
||||||
static struct rfkill *wwan_rfkill;
|
|
||||||
|
|
||||||
static const struct dmi_system_id __initdata dell_device_table[] = {
|
static const struct dmi_system_id dell_device_table[] __initconst = {
|
||||||
{
|
{
|
||||||
.ident = "Dell laptop",
|
.ident = "Dell laptop",
|
||||||
.matches = {
|
.matches = {
|
||||||
@ -119,53 +115,6 @@ static const struct dmi_system_id __initdata dell_device_table[] = {
|
|||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(dmi, dell_device_table);
|
MODULE_DEVICE_TABLE(dmi, dell_device_table);
|
||||||
|
|
||||||
static struct dmi_system_id __devinitdata dell_blacklist[] = {
|
|
||||||
/* Supported by compal-laptop */
|
|
||||||
{
|
|
||||||
.ident = "Dell Mini 9",
|
|
||||||
.matches = {
|
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 910"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.ident = "Dell Mini 10",
|
|
||||||
.matches = {
|
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1010"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.ident = "Dell Mini 10v",
|
|
||||||
.matches = {
|
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1011"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.ident = "Dell Mini 1012",
|
|
||||||
.matches = {
|
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.ident = "Dell Inspiron 11z",
|
|
||||||
.matches = {
|
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1110"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.ident = "Dell Mini 12",
|
|
||||||
.matches = {
|
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1210"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct dmi_system_id __devinitdata dell_quirks[] = {
|
static struct dmi_system_id __devinitdata dell_quirks[] = {
|
||||||
{
|
{
|
||||||
.callback = dmi_matched,
|
.callback = dmi_matched,
|
||||||
@ -185,6 +134,15 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {
|
|||||||
},
|
},
|
||||||
.driver_data = &quirk_dell_vostro_v130,
|
.driver_data = &quirk_dell_vostro_v130,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.callback = dmi_matched,
|
||||||
|
.ident = "Dell Vostro 3350",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3350"),
|
||||||
|
},
|
||||||
|
.driver_data = &quirk_dell_vostro_v130,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.callback = dmi_matched,
|
.callback = dmi_matched,
|
||||||
.ident = "Dell Vostro 3555",
|
.ident = "Dell Vostro 3555",
|
||||||
@ -212,6 +170,42 @@ static struct dmi_system_id __devinitdata dell_quirks[] = {
|
|||||||
},
|
},
|
||||||
.driver_data = &quirk_dell_vostro_v130,
|
.driver_data = &quirk_dell_vostro_v130,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.callback = dmi_matched,
|
||||||
|
.ident = "Dell Vostro 3360",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3360"),
|
||||||
|
},
|
||||||
|
.driver_data = &quirk_dell_vostro_v130,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.callback = dmi_matched,
|
||||||
|
.ident = "Dell Vostro 3460",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3460"),
|
||||||
|
},
|
||||||
|
.driver_data = &quirk_dell_vostro_v130,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.callback = dmi_matched,
|
||||||
|
.ident = "Dell Vostro 3560",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3560"),
|
||||||
|
},
|
||||||
|
.driver_data = &quirk_dell_vostro_v130,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.callback = dmi_matched,
|
||||||
|
.ident = "Dell Vostro 3450",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Dell System Vostro 3450"),
|
||||||
|
},
|
||||||
|
.driver_data = &quirk_dell_vostro_v130,
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -305,94 +299,6 @@ dell_send_request(struct calling_interface_buffer *buffer, int class,
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Derived from information in DellWirelessCtl.cpp:
|
|
||||||
Class 17, select 11 is radio control. It returns an array of 32-bit values.
|
|
||||||
|
|
||||||
Input byte 0 = 0: Wireless information
|
|
||||||
|
|
||||||
result[0]: return code
|
|
||||||
result[1]:
|
|
||||||
Bit 0: Hardware switch supported
|
|
||||||
Bit 1: Wifi locator supported
|
|
||||||
Bit 2: Wifi is supported
|
|
||||||
Bit 3: Bluetooth is supported
|
|
||||||
Bit 4: WWAN is supported
|
|
||||||
Bit 5: Wireless keyboard supported
|
|
||||||
Bits 6-7: Reserved
|
|
||||||
Bit 8: Wifi is installed
|
|
||||||
Bit 9: Bluetooth is installed
|
|
||||||
Bit 10: WWAN is installed
|
|
||||||
Bits 11-15: Reserved
|
|
||||||
Bit 16: Hardware switch is on
|
|
||||||
Bit 17: Wifi is blocked
|
|
||||||
Bit 18: Bluetooth is blocked
|
|
||||||
Bit 19: WWAN is blocked
|
|
||||||
Bits 20-31: Reserved
|
|
||||||
result[2]: NVRAM size in bytes
|
|
||||||
result[3]: NVRAM format version number
|
|
||||||
|
|
||||||
Input byte 0 = 2: Wireless switch configuration
|
|
||||||
result[0]: return code
|
|
||||||
result[1]:
|
|
||||||
Bit 0: Wifi controlled by switch
|
|
||||||
Bit 1: Bluetooth controlled by switch
|
|
||||||
Bit 2: WWAN controlled by switch
|
|
||||||
Bits 3-6: Reserved
|
|
||||||
Bit 7: Wireless switch config locked
|
|
||||||
Bit 8: Wifi locator enabled
|
|
||||||
Bits 9-14: Reserved
|
|
||||||
Bit 15: Wifi locator setting locked
|
|
||||||
Bits 16-31: Reserved
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int dell_rfkill_set(void *data, bool blocked)
|
|
||||||
{
|
|
||||||
int disable = blocked ? 1 : 0;
|
|
||||||
unsigned long radio = (unsigned long)data;
|
|
||||||
int hwswitch_bit = (unsigned long)data - 1;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
get_buffer();
|
|
||||||
dell_send_request(buffer, 17, 11);
|
|
||||||
|
|
||||||
/* If the hardware switch controls this radio, and the hardware
|
|
||||||
switch is disabled, don't allow changing the software state */
|
|
||||||
if ((hwswitch_state & BIT(hwswitch_bit)) &&
|
|
||||||
!(buffer->output[1] & BIT(16))) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer->input[0] = (1 | (radio<<8) | (disable << 16));
|
|
||||||
dell_send_request(buffer, 17, 11);
|
|
||||||
|
|
||||||
out:
|
|
||||||
release_buffer();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dell_rfkill_query(struct rfkill *rfkill, void *data)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
int bit = (unsigned long)data + 16;
|
|
||||||
int hwswitch_bit = (unsigned long)data - 1;
|
|
||||||
|
|
||||||
get_buffer();
|
|
||||||
dell_send_request(buffer, 17, 11);
|
|
||||||
status = buffer->output[1];
|
|
||||||
release_buffer();
|
|
||||||
|
|
||||||
rfkill_set_sw_state(rfkill, !!(status & BIT(bit)));
|
|
||||||
|
|
||||||
if (hwswitch_state & (BIT(hwswitch_bit)))
|
|
||||||
rfkill_set_hw_state(rfkill, !(status & BIT(16)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct rfkill_ops dell_rfkill_ops = {
|
|
||||||
.set_block = dell_rfkill_set,
|
|
||||||
.query = dell_rfkill_query,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct dentry *dell_laptop_dir;
|
static struct dentry *dell_laptop_dir;
|
||||||
|
|
||||||
static int dell_debugfs_show(struct seq_file *s, void *data)
|
static int dell_debugfs_show(struct seq_file *s, void *data)
|
||||||
@ -462,108 +368,6 @@ static const struct file_operations dell_debugfs_fops = {
|
|||||||
.release = single_release,
|
.release = single_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dell_update_rfkill(struct work_struct *ignored)
|
|
||||||
{
|
|
||||||
if (wifi_rfkill)
|
|
||||||
dell_rfkill_query(wifi_rfkill, (void *)1);
|
|
||||||
if (bluetooth_rfkill)
|
|
||||||
dell_rfkill_query(bluetooth_rfkill, (void *)2);
|
|
||||||
if (wwan_rfkill)
|
|
||||||
dell_rfkill_query(wwan_rfkill, (void *)3);
|
|
||||||
}
|
|
||||||
static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill);
|
|
||||||
|
|
||||||
|
|
||||||
static int __init dell_setup_rfkill(void)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (dmi_check_system(dell_blacklist)) {
|
|
||||||
pr_info("Blacklisted hardware detected - not enabling rfkill\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_buffer();
|
|
||||||
dell_send_request(buffer, 17, 11);
|
|
||||||
status = buffer->output[1];
|
|
||||||
buffer->input[0] = 0x2;
|
|
||||||
dell_send_request(buffer, 17, 11);
|
|
||||||
hwswitch_state = buffer->output[1];
|
|
||||||
release_buffer();
|
|
||||||
|
|
||||||
if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
|
|
||||||
wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev,
|
|
||||||
RFKILL_TYPE_WLAN,
|
|
||||||
&dell_rfkill_ops, (void *) 1);
|
|
||||||
if (!wifi_rfkill) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err_wifi;
|
|
||||||
}
|
|
||||||
ret = rfkill_register(wifi_rfkill);
|
|
||||||
if (ret)
|
|
||||||
goto err_wifi;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {
|
|
||||||
bluetooth_rfkill = rfkill_alloc("dell-bluetooth",
|
|
||||||
&platform_device->dev,
|
|
||||||
RFKILL_TYPE_BLUETOOTH,
|
|
||||||
&dell_rfkill_ops, (void *) 2);
|
|
||||||
if (!bluetooth_rfkill) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err_bluetooth;
|
|
||||||
}
|
|
||||||
ret = rfkill_register(bluetooth_rfkill);
|
|
||||||
if (ret)
|
|
||||||
goto err_bluetooth;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {
|
|
||||||
wwan_rfkill = rfkill_alloc("dell-wwan",
|
|
||||||
&platform_device->dev,
|
|
||||||
RFKILL_TYPE_WWAN,
|
|
||||||
&dell_rfkill_ops, (void *) 3);
|
|
||||||
if (!wwan_rfkill) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err_wwan;
|
|
||||||
}
|
|
||||||
ret = rfkill_register(wwan_rfkill);
|
|
||||||
if (ret)
|
|
||||||
goto err_wwan;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
err_wwan:
|
|
||||||
rfkill_destroy(wwan_rfkill);
|
|
||||||
if (bluetooth_rfkill)
|
|
||||||
rfkill_unregister(bluetooth_rfkill);
|
|
||||||
err_bluetooth:
|
|
||||||
rfkill_destroy(bluetooth_rfkill);
|
|
||||||
if (wifi_rfkill)
|
|
||||||
rfkill_unregister(wifi_rfkill);
|
|
||||||
err_wifi:
|
|
||||||
rfkill_destroy(wifi_rfkill);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dell_cleanup_rfkill(void)
|
|
||||||
{
|
|
||||||
if (wifi_rfkill) {
|
|
||||||
rfkill_unregister(wifi_rfkill);
|
|
||||||
rfkill_destroy(wifi_rfkill);
|
|
||||||
}
|
|
||||||
if (bluetooth_rfkill) {
|
|
||||||
rfkill_unregister(bluetooth_rfkill);
|
|
||||||
rfkill_destroy(bluetooth_rfkill);
|
|
||||||
}
|
|
||||||
if (wwan_rfkill) {
|
|
||||||
rfkill_unregister(wwan_rfkill);
|
|
||||||
rfkill_destroy(wwan_rfkill);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dell_send_intensity(struct backlight_device *bd)
|
static int dell_send_intensity(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -655,30 +459,6 @@ static void touchpad_led_exit(void)
|
|||||||
led_classdev_unregister(&touchpad_led);
|
led_classdev_unregister(&touchpad_led);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str,
|
|
||||||
struct serio *port)
|
|
||||||
{
|
|
||||||
static bool extended;
|
|
||||||
|
|
||||||
if (str & 0x20)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (unlikely(data == 0xe0)) {
|
|
||||||
extended = true;
|
|
||||||
return false;
|
|
||||||
} else if (unlikely(extended)) {
|
|
||||||
switch (data) {
|
|
||||||
case 0x8:
|
|
||||||
schedule_delayed_work(&dell_rfkill_work,
|
|
||||||
round_jiffies_relative(HZ));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
extended = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init dell_init(void)
|
static int __init dell_init(void)
|
||||||
{
|
{
|
||||||
int max_intensity = 0;
|
int max_intensity = 0;
|
||||||
@ -720,26 +500,10 @@ static int __init dell_init(void)
|
|||||||
goto fail_buffer;
|
goto fail_buffer;
|
||||||
buffer = page_address(bufferpage);
|
buffer = page_address(bufferpage);
|
||||||
|
|
||||||
ret = dell_setup_rfkill();
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
pr_warn("Unable to setup rfkill\n");
|
|
||||||
goto fail_rfkill;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = i8042_install_filter(dell_laptop_i8042_filter);
|
|
||||||
if (ret) {
|
|
||||||
pr_warn("Unable to install key filter\n");
|
|
||||||
goto fail_filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quirks && quirks->touchpad_led)
|
if (quirks && quirks->touchpad_led)
|
||||||
touchpad_led_init(&platform_device->dev);
|
touchpad_led_init(&platform_device->dev);
|
||||||
|
|
||||||
dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL);
|
dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL);
|
||||||
if (dell_laptop_dir != NULL)
|
|
||||||
debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL,
|
|
||||||
&dell_debugfs_fops);
|
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
/* In the event of an ACPI backlight being available, don't
|
/* In the event of an ACPI backlight being available, don't
|
||||||
@ -782,11 +546,6 @@ static int __init dell_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_backlight:
|
fail_backlight:
|
||||||
i8042_remove_filter(dell_laptop_i8042_filter);
|
|
||||||
cancel_delayed_work_sync(&dell_rfkill_work);
|
|
||||||
fail_filter:
|
|
||||||
dell_cleanup_rfkill();
|
|
||||||
fail_rfkill:
|
|
||||||
free_page((unsigned long)bufferpage);
|
free_page((unsigned long)bufferpage);
|
||||||
fail_buffer:
|
fail_buffer:
|
||||||
platform_device_del(platform_device);
|
platform_device_del(platform_device);
|
||||||
@ -804,10 +563,7 @@ static void __exit dell_exit(void)
|
|||||||
debugfs_remove_recursive(dell_laptop_dir);
|
debugfs_remove_recursive(dell_laptop_dir);
|
||||||
if (quirks && quirks->touchpad_led)
|
if (quirks && quirks->touchpad_led)
|
||||||
touchpad_led_exit();
|
touchpad_led_exit();
|
||||||
i8042_remove_filter(dell_laptop_i8042_filter);
|
|
||||||
cancel_delayed_work_sync(&dell_rfkill_work);
|
|
||||||
backlight_device_unregister(dell_backlight_device);
|
backlight_device_unregister(dell_backlight_device);
|
||||||
dell_cleanup_rfkill();
|
|
||||||
if (platform_device) {
|
if (platform_device) {
|
||||||
platform_device_unregister(platform_device);
|
platform_device_unregister(platform_device);
|
||||||
platform_driver_unregister(&platform_driver);
|
platform_driver_unregister(&platform_driver);
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
* 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
|
* 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
@ -34,7 +36,8 @@
|
|||||||
#define ACPI_FUJITSU_CLASS "fujitsu"
|
#define ACPI_FUJITSU_CLASS "fujitsu"
|
||||||
|
|
||||||
#define INVERT_TABLET_MODE_BIT 0x01
|
#define INVERT_TABLET_MODE_BIT 0x01
|
||||||
#define FORCE_TABLET_MODE_IF_UNDOCK 0x02
|
#define INVERT_DOCK_STATE_BIT 0x02
|
||||||
|
#define FORCE_TABLET_MODE_IF_UNDOCK 0x04
|
||||||
|
|
||||||
#define KEYMAP_LEN 16
|
#define KEYMAP_LEN 16
|
||||||
|
|
||||||
@ -161,6 +164,8 @@ static void fujitsu_send_state(void)
|
|||||||
state = fujitsu_read_register(0xdd);
|
state = fujitsu_read_register(0xdd);
|
||||||
|
|
||||||
dock = state & 0x02;
|
dock = state & 0x02;
|
||||||
|
if (fujitsu.config.quirks & INVERT_DOCK_STATE_BIT)
|
||||||
|
dock = !dock;
|
||||||
|
|
||||||
if ((fujitsu.config.quirks & FORCE_TABLET_MODE_IF_UNDOCK) && (!dock)) {
|
if ((fujitsu.config.quirks & FORCE_TABLET_MODE_IF_UNDOCK) && (!dock)) {
|
||||||
tablet_mode = 1;
|
tablet_mode = 1;
|
||||||
@ -221,9 +226,6 @@ static int __devinit input_fujitsu_setup(struct device *parent,
|
|||||||
input_set_capability(idev, EV_SW, SW_DOCK);
|
input_set_capability(idev, EV_SW, SW_DOCK);
|
||||||
input_set_capability(idev, EV_SW, SW_TABLET_MODE);
|
input_set_capability(idev, EV_SW, SW_TABLET_MODE);
|
||||||
|
|
||||||
input_set_capability(idev, EV_SW, SW_DOCK);
|
|
||||||
input_set_capability(idev, EV_SW, SW_TABLET_MODE);
|
|
||||||
|
|
||||||
error = input_register_device(idev);
|
error = input_register_device(idev);
|
||||||
if (error) {
|
if (error) {
|
||||||
input_free_device(idev);
|
input_free_device(idev);
|
||||||
@ -275,25 +277,31 @@ static irqreturn_t fujitsu_interrupt(int irq, void *dev_id)
|
|||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit fujitsu_dmi_default(const struct dmi_system_id *dmi)
|
static void __devinit fujitsu_dmi_common(const struct dmi_system_id *dmi)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO MODULENAME ": %s\n", dmi->ident);
|
pr_info("%s\n", dmi->ident);
|
||||||
memcpy(fujitsu.config.keymap, dmi->driver_data,
|
memcpy(fujitsu.config.keymap, dmi->driver_data,
|
||||||
sizeof(fujitsu.config.keymap));
|
sizeof(fujitsu.config.keymap));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devinit fujitsu_dmi_lifebook(const struct dmi_system_id *dmi)
|
||||||
|
{
|
||||||
|
fujitsu_dmi_common(dmi);
|
||||||
|
fujitsu.config.quirks |= INVERT_TABLET_MODE_BIT;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __devinit fujitsu_dmi_stylistic(const struct dmi_system_id *dmi)
|
static int __devinit fujitsu_dmi_stylistic(const struct dmi_system_id *dmi)
|
||||||
{
|
{
|
||||||
fujitsu_dmi_default(dmi);
|
fujitsu_dmi_common(dmi);
|
||||||
fujitsu.config.quirks |= FORCE_TABLET_MODE_IF_UNDOCK;
|
fujitsu.config.quirks |= FORCE_TABLET_MODE_IF_UNDOCK;
|
||||||
fujitsu.config.quirks |= INVERT_TABLET_MODE_BIT;
|
fujitsu.config.quirks |= INVERT_DOCK_STATE_BIT;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dmi_system_id dmi_ids[] __initconst = {
|
static struct dmi_system_id dmi_ids[] __initconst = {
|
||||||
{
|
{
|
||||||
.callback = fujitsu_dmi_default,
|
.callback = fujitsu_dmi_lifebook,
|
||||||
.ident = "Fujitsu Siemens P/T Series",
|
.ident = "Fujitsu Siemens P/T Series",
|
||||||
.matches = {
|
.matches = {
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
|
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
|
||||||
@ -302,7 +310,7 @@ static struct dmi_system_id dmi_ids[] __initconst = {
|
|||||||
.driver_data = keymap_Lifebook_Tseries
|
.driver_data = keymap_Lifebook_Tseries
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.callback = fujitsu_dmi_default,
|
.callback = fujitsu_dmi_lifebook,
|
||||||
.ident = "Fujitsu Lifebook T Series",
|
.ident = "Fujitsu Lifebook T Series",
|
||||||
.matches = {
|
.matches = {
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
|
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
|
||||||
@ -320,7 +328,7 @@ static struct dmi_system_id dmi_ids[] __initconst = {
|
|||||||
.driver_data = keymap_Stylistic_Tseries
|
.driver_data = keymap_Stylistic_Tseries
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.callback = fujitsu_dmi_default,
|
.callback = fujitsu_dmi_lifebook,
|
||||||
.ident = "Fujitsu LifeBook U810",
|
.ident = "Fujitsu LifeBook U810",
|
||||||
.matches = {
|
.matches = {
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
|
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
|
||||||
@ -347,7 +355,7 @@ static struct dmi_system_id dmi_ids[] __initconst = {
|
|||||||
.driver_data = keymap_Stylistic_ST5xxx
|
.driver_data = keymap_Stylistic_ST5xxx
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.callback = fujitsu_dmi_default,
|
.callback = fujitsu_dmi_lifebook,
|
||||||
.ident = "Unknown (using defaults)",
|
.ident = "Unknown (using defaults)",
|
||||||
.matches = {
|
.matches = {
|
||||||
DMI_MATCH(DMI_SYS_VENDOR, ""),
|
DMI_MATCH(DMI_SYS_VENDOR, ""),
|
||||||
@ -473,6 +481,6 @@ module_exit(fujitsu_module_exit);
|
|||||||
MODULE_AUTHOR("Robert Gerlach <khnz@gmx.de>");
|
MODULE_AUTHOR("Robert Gerlach <khnz@gmx.de>");
|
||||||
MODULE_DESCRIPTION("Fujitsu tablet pc extras driver");
|
MODULE_DESCRIPTION("Fujitsu tablet pc extras driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION("2.4");
|
MODULE_VERSION("2.5");
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(acpi, fujitsu_ids);
|
MODULE_DEVICE_TABLE(acpi, fujitsu_ids);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* hdaps.c - driver for IBM's Hard Drive Active Protection System
|
* hdaps.c - driver for IBM's Hard Drive Active Protection System
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005 Robert Love <rml@novell.com>
|
* Copyright (C) 2005 Robert Love <rml@novell.com>
|
||||||
* Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com>
|
* Copyright (C) 2005 Jesper Juhl <jj@chaosbits.net>
|
||||||
*
|
*
|
||||||
* The HardDisk Active Protection System (hdaps) is present in IBM ThinkPads
|
* The HardDisk Active Protection System (hdaps) is present in IBM ThinkPads
|
||||||
* starting with the R40, T41, and X40. It provides a basic two-axis
|
* starting with the R40, T41, and X40. It provides a basic two-axis
|
||||||
|
@ -634,6 +634,8 @@ static int __devinit hp_wmi_rfkill_setup(struct platform_device *device)
|
|||||||
RFKILL_TYPE_WLAN,
|
RFKILL_TYPE_WLAN,
|
||||||
&hp_wmi_rfkill_ops,
|
&hp_wmi_rfkill_ops,
|
||||||
(void *) HPWMI_WIFI);
|
(void *) HPWMI_WIFI);
|
||||||
|
if (!wifi_rfkill)
|
||||||
|
return -ENOMEM;
|
||||||
rfkill_init_sw_state(wifi_rfkill,
|
rfkill_init_sw_state(wifi_rfkill,
|
||||||
hp_wmi_get_sw_state(HPWMI_WIFI));
|
hp_wmi_get_sw_state(HPWMI_WIFI));
|
||||||
rfkill_set_hw_state(wifi_rfkill,
|
rfkill_set_hw_state(wifi_rfkill,
|
||||||
@ -648,6 +650,10 @@ static int __devinit hp_wmi_rfkill_setup(struct platform_device *device)
|
|||||||
RFKILL_TYPE_BLUETOOTH,
|
RFKILL_TYPE_BLUETOOTH,
|
||||||
&hp_wmi_rfkill_ops,
|
&hp_wmi_rfkill_ops,
|
||||||
(void *) HPWMI_BLUETOOTH);
|
(void *) HPWMI_BLUETOOTH);
|
||||||
|
if (!bluetooth_rfkill) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto register_wifi_error;
|
||||||
|
}
|
||||||
rfkill_init_sw_state(bluetooth_rfkill,
|
rfkill_init_sw_state(bluetooth_rfkill,
|
||||||
hp_wmi_get_sw_state(HPWMI_BLUETOOTH));
|
hp_wmi_get_sw_state(HPWMI_BLUETOOTH));
|
||||||
rfkill_set_hw_state(bluetooth_rfkill,
|
rfkill_set_hw_state(bluetooth_rfkill,
|
||||||
@ -662,6 +668,10 @@ static int __devinit hp_wmi_rfkill_setup(struct platform_device *device)
|
|||||||
RFKILL_TYPE_WWAN,
|
RFKILL_TYPE_WWAN,
|
||||||
&hp_wmi_rfkill_ops,
|
&hp_wmi_rfkill_ops,
|
||||||
(void *) HPWMI_WWAN);
|
(void *) HPWMI_WWAN);
|
||||||
|
if (!wwan_rfkill) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto register_bluetooth_error;
|
||||||
|
}
|
||||||
rfkill_init_sw_state(wwan_rfkill,
|
rfkill_init_sw_state(wwan_rfkill,
|
||||||
hp_wmi_get_sw_state(HPWMI_WWAN));
|
hp_wmi_get_sw_state(HPWMI_WWAN));
|
||||||
rfkill_set_hw_state(wwan_rfkill,
|
rfkill_set_hw_state(wwan_rfkill,
|
||||||
|
@ -194,7 +194,6 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data)
|
|||||||
/*
|
/*
|
||||||
* debugfs
|
* debugfs
|
||||||
*/
|
*/
|
||||||
#define DEBUGFS_EVENT_LEN (4096)
|
|
||||||
static int debugfs_status_show(struct seq_file *s, void *data)
|
static int debugfs_status_show(struct seq_file *s, void *data)
|
||||||
{
|
{
|
||||||
unsigned long value;
|
unsigned long value;
|
||||||
@ -315,7 +314,7 @@ static int __devinit ideapad_debugfs_init(struct ideapad_private *priv)
|
|||||||
node = debugfs_create_file("status", S_IRUGO, priv->debug, NULL,
|
node = debugfs_create_file("status", S_IRUGO, priv->debug, NULL,
|
||||||
&debugfs_status_fops);
|
&debugfs_status_fops);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
pr_err("failed to create event in debugfs");
|
pr_err("failed to create status in debugfs");
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -785,6 +784,10 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
|
|||||||
case 9:
|
case 9:
|
||||||
ideapad_sync_rfk_state(priv);
|
ideapad_sync_rfk_state(priv);
|
||||||
break;
|
break;
|
||||||
|
case 13:
|
||||||
|
case 6:
|
||||||
|
ideapad_input_report(priv, vpc_bit);
|
||||||
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
ideapad_backlight_notify_brightness(priv);
|
ideapad_backlight_notify_brightness(priv);
|
||||||
break;
|
break;
|
||||||
@ -795,7 +798,7 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
|
|||||||
ideapad_backlight_notify_power(priv);
|
ideapad_backlight_notify_power(priv);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ideapad_input_report(priv, vpc_bit);
|
pr_info("Unknown event: %lu\n", vpc_bit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -3402,7 +3402,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
|
|||||||
/* Do not issue duplicate brightness change events to
|
/* Do not issue duplicate brightness change events to
|
||||||
* userspace. tpacpi_detect_brightness_capabilities() must have
|
* userspace. tpacpi_detect_brightness_capabilities() must have
|
||||||
* been called before this point */
|
* been called before this point */
|
||||||
if (tp_features.bright_acpimode && acpi_video_backlight_support()) {
|
if (acpi_video_backlight_support()) {
|
||||||
pr_info("This ThinkPad has standard ACPI backlight "
|
pr_info("This ThinkPad has standard ACPI backlight "
|
||||||
"brightness control, supported by the ACPI "
|
"brightness control, supported by the ACPI "
|
||||||
"video driver\n");
|
"video driver\n");
|
||||||
|
@ -95,6 +95,7 @@ MODULE_LICENSE("GPL");
|
|||||||
|
|
||||||
/* registers */
|
/* registers */
|
||||||
#define HCI_FAN 0x0004
|
#define HCI_FAN 0x0004
|
||||||
|
#define HCI_TR_BACKLIGHT 0x0005
|
||||||
#define HCI_SYSTEM_EVENT 0x0016
|
#define HCI_SYSTEM_EVENT 0x0016
|
||||||
#define HCI_VIDEO_OUT 0x001c
|
#define HCI_VIDEO_OUT 0x001c
|
||||||
#define HCI_HOTKEY_EVENT 0x001e
|
#define HCI_HOTKEY_EVENT 0x001e
|
||||||
@ -134,6 +135,7 @@ struct toshiba_acpi_dev {
|
|||||||
unsigned int system_event_supported:1;
|
unsigned int system_event_supported:1;
|
||||||
unsigned int ntfy_supported:1;
|
unsigned int ntfy_supported:1;
|
||||||
unsigned int info_supported:1;
|
unsigned int info_supported:1;
|
||||||
|
unsigned int tr_backlight_supported:1;
|
||||||
|
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
};
|
};
|
||||||
@ -478,34 +480,70 @@ static const struct rfkill_ops toshiba_rfk_ops = {
|
|||||||
.poll = bt_rfkill_poll,
|
.poll = bt_rfkill_poll,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int get_tr_backlight_status(struct toshiba_acpi_dev *dev, bool *enabled)
|
||||||
|
{
|
||||||
|
u32 hci_result;
|
||||||
|
u32 status;
|
||||||
|
|
||||||
|
hci_read1(dev, HCI_TR_BACKLIGHT, &status, &hci_result);
|
||||||
|
*enabled = !status;
|
||||||
|
return hci_result == HCI_SUCCESS ? 0 : -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_tr_backlight_status(struct toshiba_acpi_dev *dev, bool enable)
|
||||||
|
{
|
||||||
|
u32 hci_result;
|
||||||
|
u32 value = !enable;
|
||||||
|
|
||||||
|
hci_write1(dev, HCI_TR_BACKLIGHT, value, &hci_result);
|
||||||
|
return hci_result == HCI_SUCCESS ? 0 : -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
|
static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
|
||||||
|
|
||||||
static int get_lcd(struct backlight_device *bd)
|
static int __get_lcd_brightness(struct toshiba_acpi_dev *dev)
|
||||||
{
|
{
|
||||||
struct toshiba_acpi_dev *dev = bl_get_data(bd);
|
|
||||||
u32 hci_result;
|
u32 hci_result;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
int brightness = 0;
|
||||||
|
|
||||||
|
if (dev->tr_backlight_supported) {
|
||||||
|
bool enabled;
|
||||||
|
int ret = get_tr_backlight_status(dev, &enabled);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
if (enabled)
|
||||||
|
return 0;
|
||||||
|
brightness++;
|
||||||
|
}
|
||||||
|
|
||||||
hci_read1(dev, HCI_LCD_BRIGHTNESS, &value, &hci_result);
|
hci_read1(dev, HCI_LCD_BRIGHTNESS, &value, &hci_result);
|
||||||
if (hci_result == HCI_SUCCESS)
|
if (hci_result == HCI_SUCCESS)
|
||||||
return (value >> HCI_LCD_BRIGHTNESS_SHIFT);
|
return brightness + (value >> HCI_LCD_BRIGHTNESS_SHIFT);
|
||||||
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_lcd_brightness(struct backlight_device *bd)
|
||||||
|
{
|
||||||
|
struct toshiba_acpi_dev *dev = bl_get_data(bd);
|
||||||
|
return __get_lcd_brightness(dev);
|
||||||
|
}
|
||||||
|
|
||||||
static int lcd_proc_show(struct seq_file *m, void *v)
|
static int lcd_proc_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
struct toshiba_acpi_dev *dev = m->private;
|
struct toshiba_acpi_dev *dev = m->private;
|
||||||
int value;
|
int value;
|
||||||
|
int levels;
|
||||||
|
|
||||||
if (!dev->backlight_dev)
|
if (!dev->backlight_dev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
value = get_lcd(dev->backlight_dev);
|
levels = dev->backlight_dev->props.max_brightness + 1;
|
||||||
|
value = get_lcd_brightness(dev->backlight_dev);
|
||||||
if (value >= 0) {
|
if (value >= 0) {
|
||||||
seq_printf(m, "brightness: %d\n", value);
|
seq_printf(m, "brightness: %d\n", value);
|
||||||
seq_printf(m, "brightness_levels: %d\n",
|
seq_printf(m, "brightness_levels: %d\n", levels);
|
||||||
HCI_LCD_BRIGHTNESS_LEVELS);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,10 +556,19 @@ static int lcd_proc_open(struct inode *inode, struct file *file)
|
|||||||
return single_open(file, lcd_proc_show, PDE(inode)->data);
|
return single_open(file, lcd_proc_show, PDE(inode)->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_lcd(struct toshiba_acpi_dev *dev, int value)
|
static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value)
|
||||||
{
|
{
|
||||||
u32 hci_result;
|
u32 hci_result;
|
||||||
|
|
||||||
|
if (dev->tr_backlight_supported) {
|
||||||
|
bool enable = !value;
|
||||||
|
int ret = set_tr_backlight_status(dev, enable);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
if (value)
|
||||||
|
value--;
|
||||||
|
}
|
||||||
|
|
||||||
value = value << HCI_LCD_BRIGHTNESS_SHIFT;
|
value = value << HCI_LCD_BRIGHTNESS_SHIFT;
|
||||||
hci_write1(dev, HCI_LCD_BRIGHTNESS, value, &hci_result);
|
hci_write1(dev, HCI_LCD_BRIGHTNESS, value, &hci_result);
|
||||||
return hci_result == HCI_SUCCESS ? 0 : -EIO;
|
return hci_result == HCI_SUCCESS ? 0 : -EIO;
|
||||||
@ -530,7 +577,7 @@ static int set_lcd(struct toshiba_acpi_dev *dev, int value)
|
|||||||
static int set_lcd_status(struct backlight_device *bd)
|
static int set_lcd_status(struct backlight_device *bd)
|
||||||
{
|
{
|
||||||
struct toshiba_acpi_dev *dev = bl_get_data(bd);
|
struct toshiba_acpi_dev *dev = bl_get_data(bd);
|
||||||
return set_lcd(dev, bd->props.brightness);
|
return set_lcd_brightness(dev, bd->props.brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
|
static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
|
||||||
@ -541,6 +588,7 @@ static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
|
|||||||
size_t len;
|
size_t len;
|
||||||
int value;
|
int value;
|
||||||
int ret;
|
int ret;
|
||||||
|
int levels = dev->backlight_dev->props.max_brightness + 1;
|
||||||
|
|
||||||
len = min(count, sizeof(cmd) - 1);
|
len = min(count, sizeof(cmd) - 1);
|
||||||
if (copy_from_user(cmd, buf, len))
|
if (copy_from_user(cmd, buf, len))
|
||||||
@ -548,8 +596,8 @@ static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
|
|||||||
cmd[len] = '\0';
|
cmd[len] = '\0';
|
||||||
|
|
||||||
if (sscanf(cmd, " brightness : %i", &value) == 1 &&
|
if (sscanf(cmd, " brightness : %i", &value) == 1 &&
|
||||||
value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
|
value >= 0 && value < levels) {
|
||||||
ret = set_lcd(dev, value);
|
ret = set_lcd_brightness(dev, value);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = count;
|
ret = count;
|
||||||
} else {
|
} else {
|
||||||
@ -860,8 +908,9 @@ static void remove_toshiba_proc_entries(struct toshiba_acpi_dev *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct backlight_ops toshiba_backlight_data = {
|
static const struct backlight_ops toshiba_backlight_data = {
|
||||||
.get_brightness = get_lcd,
|
.options = BL_CORE_SUSPENDRESUME,
|
||||||
.update_status = set_lcd_status,
|
.get_brightness = get_lcd_brightness,
|
||||||
|
.update_status = set_lcd_status,
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str,
|
static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str,
|
||||||
@ -1020,6 +1069,56 @@ static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __devinit toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev)
|
||||||
|
{
|
||||||
|
struct backlight_properties props;
|
||||||
|
int brightness;
|
||||||
|
int ret;
|
||||||
|
bool enabled;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some machines don't support the backlight methods at all, and
|
||||||
|
* others support it read-only. Either of these is pretty useless,
|
||||||
|
* so only register the backlight device if the backlight method
|
||||||
|
* supports both reads and writes.
|
||||||
|
*/
|
||||||
|
brightness = __get_lcd_brightness(dev);
|
||||||
|
if (brightness < 0)
|
||||||
|
return 0;
|
||||||
|
ret = set_lcd_brightness(dev, brightness);
|
||||||
|
if (ret) {
|
||||||
|
pr_debug("Backlight method is read-only, disabling backlight support\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine whether or not BIOS supports transflective backlight */
|
||||||
|
ret = get_tr_backlight_status(dev, &enabled);
|
||||||
|
dev->tr_backlight_supported = !ret;
|
||||||
|
|
||||||
|
memset(&props, 0, sizeof(props));
|
||||||
|
props.type = BACKLIGHT_PLATFORM;
|
||||||
|
props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
|
||||||
|
|
||||||
|
/* adding an extra level and having 0 change to transflective mode */
|
||||||
|
if (dev->tr_backlight_supported)
|
||||||
|
props.max_brightness++;
|
||||||
|
|
||||||
|
dev->backlight_dev = backlight_device_register("toshiba",
|
||||||
|
&dev->acpi_dev->dev,
|
||||||
|
dev,
|
||||||
|
&toshiba_backlight_data,
|
||||||
|
&props);
|
||||||
|
if (IS_ERR(dev->backlight_dev)) {
|
||||||
|
ret = PTR_ERR(dev->backlight_dev);
|
||||||
|
pr_err("Could not register toshiba backlight device\n");
|
||||||
|
dev->backlight_dev = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->backlight_dev->props.brightness = brightness;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type)
|
static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type)
|
||||||
{
|
{
|
||||||
struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
|
struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev);
|
||||||
@ -1078,7 +1177,6 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev)
|
|||||||
u32 dummy;
|
u32 dummy;
|
||||||
bool bt_present;
|
bool bt_present;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct backlight_properties props;
|
|
||||||
|
|
||||||
if (toshiba_acpi)
|
if (toshiba_acpi)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
@ -1104,22 +1202,9 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev)
|
|||||||
|
|
||||||
mutex_init(&dev->mutex);
|
mutex_init(&dev->mutex);
|
||||||
|
|
||||||
memset(&props, 0, sizeof(props));
|
ret = toshiba_acpi_setup_backlight(dev);
|
||||||
props.type = BACKLIGHT_PLATFORM;
|
if (ret)
|
||||||
props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
|
|
||||||
dev->backlight_dev = backlight_device_register("toshiba",
|
|
||||||
&acpi_dev->dev,
|
|
||||||
dev,
|
|
||||||
&toshiba_backlight_data,
|
|
||||||
&props);
|
|
||||||
if (IS_ERR(dev->backlight_dev)) {
|
|
||||||
ret = PTR_ERR(dev->backlight_dev);
|
|
||||||
|
|
||||||
pr_err("Could not register toshiba backlight device\n");
|
|
||||||
dev->backlight_dev = NULL;
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
dev->backlight_dev->props.brightness = get_lcd(dev->backlight_dev);
|
|
||||||
|
|
||||||
/* Register rfkill switch for Bluetooth */
|
/* Register rfkill switch for Bluetooth */
|
||||||
if (hci_get_bt_present(dev, &bt_present) == HCI_SUCCESS && bt_present) {
|
if (hci_get_bt_present(dev, &bt_present) == HCI_SUCCESS && bt_present) {
|
||||||
|
@ -15,15 +15,26 @@
|
|||||||
|
|
||||||
#include <asm/olpc.h>
|
#include <asm/olpc.h>
|
||||||
|
|
||||||
|
static bool card_blocked;
|
||||||
|
|
||||||
static int rfkill_set_block(void *data, bool blocked)
|
static int rfkill_set_block(void *data, bool blocked)
|
||||||
{
|
{
|
||||||
unsigned char cmd;
|
unsigned char cmd;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (blocked == card_blocked)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (blocked)
|
if (blocked)
|
||||||
cmd = EC_WLAN_ENTER_RESET;
|
cmd = EC_WLAN_ENTER_RESET;
|
||||||
else
|
else
|
||||||
cmd = EC_WLAN_LEAVE_RESET;
|
cmd = EC_WLAN_LEAVE_RESET;
|
||||||
|
|
||||||
return olpc_ec_cmd(cmd, NULL, 0, NULL, 0);
|
r = olpc_ec_cmd(cmd, NULL, 0, NULL, 0);
|
||||||
|
if (r == 0)
|
||||||
|
card_blocked = blocked;
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct rfkill_ops rfkill_ops = {
|
static const struct rfkill_ops rfkill_ops = {
|
||||||
|
Loading…
Reference in New Issue
Block a user