lkml.org 
[lkml]   [2007]   [Oct]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRe: [PATCH] Add bluetooth support to toshiba-acpi driver
    Date
    Jonathan McDowell wrote:

    > This patch adds bluetooth support to the toshiba-acpi driver. I have
    > tried to follow the same format for the /proc/acpi/toshiba/bluetooth
    > file as followed in the thinkpad-acpi driver. In the long term the
    > rfkill infrastructure looks like the way forward for this functionality,
    > but at present it doesn't seem to be suitable.
    >

    Would it be possible (make sense) to add config option for that? There are
    probably a bunch of older models out there that do not have BT at all (I am
    owner of such one).

    Thank you

    -andrey

    > Traditionally the userland "toshset" program would have been used to
    > enable bluetooth, but this requires either CONFIG_TOSHIBA or a patched
    > toshiba-acpi to emulate the /dev/toshiba device. Also toshset doesn't
    > currently run in 64bit mode.
    >
    > Patch has been successfully tested on a Portégé R200 (in 32bit mode) and
    > an R500 (in 64bit mode).
    >
    > Signed-Off-By: Jonathan McDowell <noodles@earth.li>
    >
    > -----
    > --- drivers/acpi/toshiba_acpi.c.orig 2007-10-21 18:29:01.000000000 +0100
    > +++ drivers/acpi/toshiba_acpi.c 2007-10-21 18:15:34.000000000 +0100
    > @@ -33,7 +33,7 @@
    > *
    > */
    >
    > -#define TOSHIBA_ACPI_VERSION "0.18"
    > +#define TOSHIBA_ACPI_VERSION "0.19"
    > #define PROC_INTERFACE_VERSION 1
    >
    > #include <linux/kernel.h>
    > @@ -55,6 +55,7 @@ MODULE_LICENSE("GPL");
    > #define MY_ERR KERN_ERR MY_LOGPREFIX
    > #define MY_NOTICE KERN_NOTICE MY_LOGPREFIX
    > #define MY_INFO KERN_INFO MY_LOGPREFIX
    > +#define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
    >
    > /* Toshiba ACPI method paths */
    > #define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM"
    > @@ -90,6 +91,7 @@ MODULE_LICENSE("GPL");
    > #define HCI_VIDEO_OUT 0x001c
    > #define HCI_HOTKEY_EVENT 0x001e
    > #define HCI_LCD_BRIGHTNESS 0x002a
    > +#define HCI_BLUETOOTH 0x0056
    >
    > /* field definitions */
    > #define HCI_LCD_BRIGHTNESS_BITS 3
    > @@ -482,6 +484,129 @@ static unsigned long write_keys(const ch
    > return count;
    > }
    >
    > +static int toshiba_bluetooth_present(void)
    > +{
    > + u32 hci_result;
    > + u32 value;
    > +
    > + hci_read1(HCI_BLUETOOTH, &value, &hci_result);
    > + if (hci_result == HCI_SUCCESS) {
    > + return (value & 0x0f) == 0x0f;
    > + } else
    > + return -EFAULT;
    > +}
    > +
    > +static int toshiba_bluetooth_get(void)
    > +{
    > + u32 in[HCI_WORDS];
    > + u32 out[HCI_WORDS];
    > + acpi_status status;
    > +
    > + in[0] = HCI_GET;
    > + in[1] = HCI_BLUETOOTH;
    > + in[2] = 0;
    > + in[3] = 1;
    > + status = hci_raw(in, out);
    > + if (status != AE_OK) {
    > + printk(MY_ERR "Error checking Bluetooth device status.\n");
    > + return -EIO;
    > + }
    > +
    > + /* 0x1 == switch on, 0x40 == attached, 0x80 == power on */
    > + return (out[2] & 0xC1) == 0xC1;
    > +}
    > +
    > +static int toshiba_bluetooth_set(int state)
    > +{
    > + u32 in[HCI_WORDS];
    > + u32 out[HCI_WORDS];
    > + acpi_status status;
    > +
    > + switch (state) {
    > + case 0:
    > + in[0] = HCI_SET;
    > + in[1] = HCI_BLUETOOTH;
    > + in[2] = 0;
    > + in[3] = 0x40;
    > + status = hci_raw(in, out);
    > + if (status != AE_OK) {
    > + printk(MY_ERR "Error detaching Bluetooth device.\n");
    > + return -EIO;
    > + }
    > +
    > + in[0] = HCI_SET;
    > + in[1] = HCI_BLUETOOTH;
    > + in[2] = 0;
    > + in[3] = 0x80;
    > + status = hci_raw(in, out);
    > + if (status != AE_OK) {
    > + printk(MY_ERR "Error deactivating Bluetooth device.\n");
    > + return -EIO;
    > + }
    > + break;
    > + case 1:
    > + in[0] = HCI_SET;
    > + in[1] = HCI_BLUETOOTH;
    > + in[2] = 1;
    > + in[3] = 0x80;
    > + status = hci_raw(in, out);
    > + if (status != AE_OK) {
    > + printk(MY_ERR "Error activating Bluetooth device.\n");
    > + return -EIO;
    > + }
    > +
    > + in[0] = HCI_SET;
    > + in[1] = HCI_BLUETOOTH;
    > + in[2] = 1;
    > + in[3] = 0x40;
    > + status = hci_raw(in, out);
    > + if (status != AE_OK) {
    > + printk(MY_ERR "Error attaching Bluetooth device.\n");
    > + return -EIO;
    > + }
    > + break;
    > + default:
    > + printk(MY_ERR "Unknown state for Bluetooth.\n");
    > + };
    > +
    > + return 0;
    > +}
    > +
    > +static char *read_bluetooth(char *p)
    > +{
    > + int value = toshiba_bluetooth_get();
    > +
    > + if (!toshiba_bluetooth_present()) {
    > + p += sprintf(p, "status:\t\tnot supported\n");
    > + } else if (value >= 0) {
    > + p += sprintf(p, "status:\t\t%s\n",
    > + value ? "enabled" : "disabled");
    > + p += sprintf(p, "commands:\tenable, disable\n");
    > + } else {
    > + printk(MY_ERR "Error reading bluetooth status.\n");
    > + }
    > +
    > + return p;
    > +}
    > +
    > +static unsigned long write_bluetooth(const char *buffer, unsigned long
    > count) +{
    > + int ret ;
    > +
    > + if (!toshiba_bluetooth_present()) {
    > + ret = -ENODEV;
    > + } else if (strlencmp(buffer, "enable") == 0) {
    > + toshiba_bluetooth_set(1);
    > + ret = count;
    > + } else if (strlencmp(buffer, "disable") == 0) {
    > + toshiba_bluetooth_set(0);
    > + ret = count;
    > + } else {
    > + ret = -EINVAL;
    > + }
    > + return ret;
    > +}
    > +
    > static char *read_version(char *p)
    > {
    > p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION);
    > @@ -496,6 +621,7 @@ static char *read_version(char *p)
    > #define PROC_TOSHIBA "toshiba"
    >
    > static ProcItem proc_items[] = {
    > + {"bluetooth", read_bluetooth, write_bluetooth},
    > {"lcd", read_lcd, write_lcd},
    > {"video", read_video, write_video},
    > {"fan", read_fan, write_fan},
    > -----
    >
    > J.
    >


    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-10-22 04:33    [W:0.035 / U:0.076 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site