Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/linville/wireless-next-2.6
  • Loading branch information
David S. Miller committed Sep 8, 2008
2 parents e2a6b85 + d10c4ec commit 9bff9db
Show file tree
Hide file tree
Showing 78 changed files with 7,632 additions and 6,424 deletions.
3 changes: 3 additions & 0 deletions drivers/acpi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ config ACPI_ASUS
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on X86
select INPUT_POLLDEV
select NET
select RFKILL
select BACKLIGHT_CLASS_DEVICE
---help---
This driver adds support for access to certain system settings
Expand Down
261 changes: 253 additions & 8 deletions drivers/acpi/toshiba_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
*
* Copyright (C) 2002-2004 John Belmonte
* Copyright (C) 2008 Philip Langdale
*
* 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
Expand Down Expand Up @@ -33,7 +34,7 @@
*
*/

#define TOSHIBA_ACPI_VERSION "0.18"
#define TOSHIBA_ACPI_VERSION "0.19"
#define PROC_INTERFACE_VERSION 1

#include <linux/kernel.h>
Expand All @@ -42,6 +43,9 @@
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
#include <linux/rfkill.h>
#include <linux/input-polldev.h>

#include <asm/uaccess.h>

Expand Down Expand Up @@ -90,6 +94,7 @@ MODULE_LICENSE("GPL");
#define HCI_VIDEO_OUT 0x001c
#define HCI_HOTKEY_EVENT 0x001e
#define HCI_LCD_BRIGHTNESS 0x002a
#define HCI_WIRELESS 0x0056

/* field definitions */
#define HCI_LCD_BRIGHTNESS_BITS 3
Expand All @@ -98,9 +103,14 @@ MODULE_LICENSE("GPL");
#define HCI_VIDEO_OUT_LCD 0x1
#define HCI_VIDEO_OUT_CRT 0x2
#define HCI_VIDEO_OUT_TV 0x4
#define HCI_WIRELESS_KILL_SWITCH 0x01
#define HCI_WIRELESS_BT_PRESENT 0x0f
#define HCI_WIRELESS_BT_ATTACH 0x40
#define HCI_WIRELESS_BT_POWER 0x80

static const struct acpi_device_id toshiba_device_ids[] = {
{"TOS6200", 0},
{"TOS6208", 0},
{"TOS1900", 0},
{"", 0},
};
Expand Down Expand Up @@ -193,7 +203,7 @@ static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
return status;
}

/* common hci tasks (get or set one value)
/* common hci tasks (get or set one or two value)
*
* In addition to the ACPI status, the HCI system returns a result which
* may be useful (such as "not supported").
Expand All @@ -218,6 +228,152 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result)
return status;
}

static acpi_status hci_write2(u32 reg, u32 in1, u32 in2, u32 *result)
{
u32 in[HCI_WORDS] = { HCI_SET, reg, in1, in2, 0, 0 };
u32 out[HCI_WORDS];
acpi_status status = hci_raw(in, out);
*result = (status == AE_OK) ? out[0] : HCI_FAILURE;
return status;
}

static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result)
{
u32 in[HCI_WORDS] = { HCI_GET, reg, *out1, *out2, 0, 0 };
u32 out[HCI_WORDS];
acpi_status status = hci_raw(in, out);
*out1 = out[2];
*out2 = out[3];
*result = (status == AE_OK) ? out[0] : HCI_FAILURE;
return status;
}

struct toshiba_acpi_dev {
struct platform_device *p_dev;
struct rfkill *rfk_dev;
struct input_polled_dev *poll_dev;

const char *bt_name;
const char *rfk_name;

bool last_rfk_state;

struct mutex mutex;
};

static struct toshiba_acpi_dev toshiba_acpi = {
.bt_name = "Toshiba Bluetooth",
.rfk_name = "Toshiba RFKill Switch",
.last_rfk_state = false,
};

/* Bluetooth rfkill handlers */

static u32 hci_get_bt_present(bool *present)
{
u32 hci_result;
u32 value, value2;

value = 0;
value2 = 0;
hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
if (hci_result == HCI_SUCCESS)
*present = (value & HCI_WIRELESS_BT_PRESENT) ? true : false;

return hci_result;
}

static u32 hci_get_bt_on(bool *on)
{
u32 hci_result;
u32 value, value2;

value = 0;
value2 = 0x0001;
hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
if (hci_result == HCI_SUCCESS)
*on = (value & HCI_WIRELESS_BT_POWER) &&
(value & HCI_WIRELESS_BT_ATTACH);

return hci_result;
}

static u32 hci_get_radio_state(bool *radio_state)
{
u32 hci_result;
u32 value, value2;

value = 0;
value2 = 0x0001;
hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);

*radio_state = value & HCI_WIRELESS_KILL_SWITCH;
return hci_result;
}

static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state)
{
u32 result1, result2;
u32 value;
bool radio_state;
struct toshiba_acpi_dev *dev = data;

value = (state == RFKILL_STATE_UNBLOCKED);

if (hci_get_radio_state(&radio_state) != HCI_SUCCESS)
return -EFAULT;

switch (state) {
case RFKILL_STATE_UNBLOCKED:
if (!radio_state)
return -EPERM;
break;
case RFKILL_STATE_SOFT_BLOCKED:
break;
default:
return -EINVAL;
}

mutex_lock(&dev->mutex);
hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1);
hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2);
mutex_unlock(&dev->mutex);

if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS)
return -EFAULT;

return 0;
}

static void bt_poll_rfkill(struct input_polled_dev *poll_dev)
{
bool state_changed;
bool new_rfk_state;
bool value;
u32 hci_result;
struct toshiba_acpi_dev *dev = poll_dev->private;

hci_result = hci_get_radio_state(&value);
if (hci_result != HCI_SUCCESS)
return; /* Can't do anything useful */

new_rfk_state = value;

mutex_lock(&dev->mutex);
state_changed = new_rfk_state != dev->last_rfk_state;
dev->last_rfk_state = new_rfk_state;
mutex_unlock(&dev->mutex);

if (unlikely(state_changed)) {
rfkill_force_state(dev->rfk_dev,
new_rfk_state ?
RFKILL_STATE_SOFT_BLOCKED :
RFKILL_STATE_HARD_BLOCKED);
input_report_switch(poll_dev->input, SW_RFKILL_ALL,
new_rfk_state);
}
}

static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
static struct backlight_device *toshiba_backlight_device;
static int force_fan;
Expand Down Expand Up @@ -547,6 +703,14 @@ static struct backlight_ops toshiba_backlight_data = {

static void toshiba_acpi_exit(void)
{
if (toshiba_acpi.poll_dev) {
input_unregister_polled_device(toshiba_acpi.poll_dev);
input_free_polled_device(toshiba_acpi.poll_dev);
}

if (toshiba_acpi.rfk_dev)
rfkill_unregister(toshiba_acpi.rfk_dev);

if (toshiba_backlight_device)
backlight_device_unregister(toshiba_backlight_device);

Expand All @@ -555,13 +719,19 @@ static void toshiba_acpi_exit(void)
if (toshiba_proc_dir)
remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);

platform_device_unregister(toshiba_acpi.p_dev);

return;
}

static int __init toshiba_acpi_init(void)
{
acpi_status status = AE_OK;
u32 hci_result;
bool bt_present;
bool bt_on;
bool radio_on;
int ret = 0;

if (acpi_disabled)
return -ENODEV;
Expand All @@ -578,6 +748,18 @@ static int __init toshiba_acpi_init(void)
TOSHIBA_ACPI_VERSION);
printk(MY_INFO " HCI method: %s\n", method_hci);

mutex_init(&toshiba_acpi.mutex);

toshiba_acpi.p_dev = platform_device_register_simple("toshiba_acpi",
-1, NULL, 0);
if (IS_ERR(toshiba_acpi.p_dev)) {
ret = PTR_ERR(toshiba_acpi.p_dev);
printk(MY_ERR "unable to register platform device\n");
toshiba_acpi.p_dev = NULL;
toshiba_acpi_exit();
return ret;
}

force_fan = 0;
key_event_valid = 0;

Expand All @@ -586,19 +768,23 @@ static int __init toshiba_acpi_init(void)

toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir);
if (!toshiba_proc_dir) {
status = AE_ERROR;
toshiba_acpi_exit();
return -ENODEV;
} else {
toshiba_proc_dir->owner = THIS_MODULE;
status = add_device();
if (ACPI_FAILURE(status))
remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
if (ACPI_FAILURE(status)) {
toshiba_acpi_exit();
return -ENODEV;
}
}

toshiba_backlight_device = backlight_device_register("toshiba",NULL,
toshiba_backlight_device = backlight_device_register("toshiba",
&toshiba_acpi.p_dev->dev,
NULL,
&toshiba_backlight_data);
if (IS_ERR(toshiba_backlight_device)) {
int ret = PTR_ERR(toshiba_backlight_device);
ret = PTR_ERR(toshiba_backlight_device);

printk(KERN_ERR "Could not register toshiba backlight device\n");
toshiba_backlight_device = NULL;
Expand All @@ -607,7 +793,66 @@ static int __init toshiba_acpi_init(void)
}
toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;

return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
/* Register rfkill switch for Bluetooth */
if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev,
RFKILL_TYPE_BLUETOOTH);
if (!toshiba_acpi.rfk_dev) {
printk(MY_ERR "unable to allocate rfkill device\n");
toshiba_acpi_exit();
return -ENOMEM;
}

toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name;
toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio;
toshiba_acpi.rfk_dev->user_claim_unsupported = 1;
toshiba_acpi.rfk_dev->data = &toshiba_acpi;

if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) {
toshiba_acpi.rfk_dev->state = RFKILL_STATE_UNBLOCKED;
} else if (hci_get_radio_state(&radio_on) == HCI_SUCCESS &&
radio_on) {
toshiba_acpi.rfk_dev->state = RFKILL_STATE_SOFT_BLOCKED;
} else {
toshiba_acpi.rfk_dev->state = RFKILL_STATE_HARD_BLOCKED;
}

ret = rfkill_register(toshiba_acpi.rfk_dev);
if (ret) {
printk(MY_ERR "unable to register rfkill device\n");
toshiba_acpi_exit();
return -ENOMEM;
}
}

/* Register input device for kill switch */
toshiba_acpi.poll_dev = input_allocate_polled_device();
if (!toshiba_acpi.poll_dev) {
printk(MY_ERR "unable to allocate kill-switch input device\n");
toshiba_acpi_exit();
return -ENOMEM;
}
toshiba_acpi.poll_dev->private = &toshiba_acpi;
toshiba_acpi.poll_dev->poll = bt_poll_rfkill;
toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */

toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name;
toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST;
toshiba_acpi.poll_dev->input->id.vendor = 0x0930; /* Toshiba USB ID */
set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit);
set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit);
input_report_switch(toshiba_acpi.poll_dev->input, SW_RFKILL_ALL, TRUE);

ret = input_register_polled_device(toshiba_acpi.poll_dev);
if (ret) {
printk(MY_ERR "unable to register kill-switch input device\n");
rfkill_free(toshiba_acpi.rfk_dev);
toshiba_acpi.rfk_dev = NULL;
toshiba_acpi_exit();
return ret;
}

return 0;
}

module_init(toshiba_acpi_init);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/adm8211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1884,6 +1884,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr);
/* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);

dev->channel_change_time = 1000;
dev->max_signal = 100; /* FIXME: find better value */
Expand Down
12 changes: 10 additions & 2 deletions drivers/net/wireless/ath5k/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
ath5k-y += base.o
ath5k-y += hw.o
ath5k-y += caps.o
ath5k-y += initvals.o
ath5k-y += eeprom.o
ath5k-y += gpio.o
ath5k-y += desc.o
ath5k-y += dma.o
ath5k-y += qcu.o
ath5k-y += pcu.o
ath5k-y += phy.o
ath5k-y += reset.o
ath5k-y += attach.o
ath5k-y += base.o
ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
obj-$(CONFIG_ATH5K) += ath5k.o
Loading

0 comments on commit 9bff9db

Please sign in to comment.