]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'thinkpad' into release
authorLen Brown <len.brown@intel.com>
Wed, 30 Dec 2009 07:51:05 +0000 (02:51 -0500)
committerLen Brown <len.brown@intel.com>
Wed, 30 Dec 2009 07:51:05 +0000 (02:51 -0500)
Documentation/laptops/thinkpad-acpi.txt
drivers/platform/x86/Kconfig
drivers/platform/x86/thinkpad_acpi.c

index 169091f75e6d2122d1b7cb9d2bf99e5a055af00e..75afa1229fd7e72059ffce02b8c450192617e0c7 100644 (file)
@@ -1092,8 +1092,8 @@ WARNING:
     its level up and down at every change.
 
 
-Volume control
---------------
+Volume control (Console Audio control)
+--------------------------------------
 
 procfs: /proc/acpi/ibm/volume
 ALSA: "ThinkPad Console Audio Control", default ID: "ThinkPadEC"
@@ -1110,9 +1110,53 @@ the desktop environment to just provide on-screen-display feedback.
 Software volume control should be done only in the main AC97/HDA
 mixer.
 
-This feature allows volume control on ThinkPad models with a digital
-volume knob (when available, not all models have it), as well as
-mute/unmute control.  The available commands are:
+
+About the ThinkPad Console Audio control:
+
+ThinkPads have a built-in amplifier and muting circuit that drives the
+console headphone and speakers.  This circuit is after the main AC97
+or HDA mixer in the audio path, and under exclusive control of the
+firmware.
+
+ThinkPads have three special hotkeys to interact with the console
+audio control: volume up, volume down and mute.
+
+It is worth noting that the normal way the mute function works (on
+ThinkPads that do not have a "mute LED") is:
+
+1. Press mute to mute.  It will *always* mute, you can press it as
+   many times as you want, and the sound will remain mute.
+
+2. Press either volume key to unmute the ThinkPad (it will _not_
+   change the volume, it will just unmute).
+
+This is a very superior design when compared to the cheap software-only
+mute-toggle solution found on normal consumer laptops:  you can be
+absolutely sure the ThinkPad will not make noise if you press the mute
+button, no matter the previous state.
+
+The IBM ThinkPads, and the earlier Lenovo ThinkPads have variable-gain
+amplifiers driving the speakers and headphone output, and the firmware
+also handles volume control for the headphone and speakers on these
+ThinkPads without any help from the operating system (this volume
+control stage exists after the main AC97 or HDA mixer in the audio
+path).
+
+The newer Lenovo models only have firmware mute control, and depend on
+the main HDA mixer to do volume control (which is done by the operating
+system).  In this case, the volume keys are filtered out for unmute
+key press (there are some firmware bugs in this area) and delivered as
+normal key presses to the operating system (thinkpad-acpi is not
+involved).
+
+
+The ThinkPad-ACPI volume control:
+
+The preferred way to interact with the Console Audio control is the
+ALSA interface.
+
+The legacy procfs interface allows one to read the current state,
+and if volume control is enabled, accepts the following commands:
 
        echo up   >/proc/acpi/ibm/volume
        echo down >/proc/acpi/ibm/volume
@@ -1121,12 +1165,10 @@ mute/unmute control.  The available commands are:
        echo 'level <level>' >/proc/acpi/ibm/volume
 
 The <level> number range is 0 to 14 although not all of them may be
-distinct. The unmute the volume after the mute command, use either the
+distinct. To unmute the volume after the mute command, use either the
 up or down command (the level command will not unmute the volume), or
 the unmute command.
 
-The current volume level and mute state is shown in the file.
-
 You can use the volume_capabilities parameter to tell the driver
 whether your thinkpad has volume control or mute-only control:
 volume_capabilities=1 for mixers with mute and volume control,
index ec4faffe6b0587da92c620e7f5d291c373d02fdf..db32c25e360591c7dd232e6463ca00d3001e00ae 100644 (file)
@@ -231,8 +231,36 @@ config THINKPAD_ACPI
 
          This driver was formerly known as ibm-acpi.
 
+         Extra functionality will be available if the rfkill (CONFIG_RFKILL)
+         and/or ALSA (CONFIG_SND) subsystems are available in the kernel.
+         Note that if you want ThinkPad-ACPI to be built-in instead of
+         modular, ALSA and rfkill will also have to be built-in.
+
          If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
 
+config THINKPAD_ACPI_ALSA_SUPPORT
+       bool "Console audio control ALSA interface"
+       depends on THINKPAD_ACPI
+       depends on SND
+       depends on SND = y || THINKPAD_ACPI = SND
+       default y
+       ---help---
+         Enables monitoring of the built-in console audio output control
+         (headphone and speakers), which is operated by the mute and (in
+         some ThinkPad models) volume hotkeys.
+
+         If this option is enabled, ThinkPad-ACPI will export an ALSA card
+         with a single read-only mixer control, which should be used for
+         on-screen-display feedback purposes by the Desktop Environment.
+
+         Optionally, the driver will also allow software control (the
+         ALSA mixer will be made read-write).  Please refer to the driver
+         documentation for details.
+
+         All IBM models have both volume and mute control.  Newer Lenovo
+         models only have mute control (the volume hotkeys are just normal
+         keys and volume control is done through the main HDA mixer).
+
 config THINKPAD_ACPI_DEBUGFACILITIES
        bool "Maintainer debug facilities"
        depends on THINKPAD_ACPI
index 448c8aeb166b1e25561be66b98649c6de4042637..e67e4feb35cb814f85ad2df10bc1836c00cc79b6 100644 (file)
@@ -6384,11 +6384,13 @@ static struct ibm_struct brightness_driver_data = {
  * and we leave them unchanged.
  */
 
+#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
+
 #define TPACPI_ALSA_DRVNAME  "ThinkPad EC"
 #define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control"
 #define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME
 
-static int alsa_index = SNDRV_DEFAULT_IDX1;
+static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */
 static char *alsa_id = "ThinkPadEC";
 static int alsa_enable = SNDRV_DEFAULT_ENABLE1;
 
@@ -6705,10 +6707,11 @@ static int __init volume_create_alsa_mixer(void)
 
        rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE,
                            sizeof(struct tpacpi_alsa_data), &card);
-       if (rc < 0)
-               return rc;
-       if (!card)
-               return -ENOMEM;
+       if (rc < 0 || !card) {
+               printk(TPACPI_ERR
+                       "Failed to create ALSA card structures: %d\n", rc);
+               return 1;
+       }
 
        BUG_ON(!card->private_data);
        data = card->private_data;
@@ -6741,8 +6744,9 @@ static int __init volume_create_alsa_mixer(void)
                rc = snd_ctl_add(card, ctl_vol);
                if (rc < 0) {
                        printk(TPACPI_ERR
-                               "Failed to create ALSA volume control\n");
-                       goto err_out;
+                               "Failed to create ALSA volume control: %d\n",
+                               rc);
+                       goto err_exit;
                }
                data->ctl_vol_id = &ctl_vol->id;
        }
@@ -6750,22 +6754,25 @@ static int __init volume_create_alsa_mixer(void)
        ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL);
        rc = snd_ctl_add(card, ctl_mute);
        if (rc < 0) {
-               printk(TPACPI_ERR "Failed to create ALSA mute control\n");
-               goto err_out;
+               printk(TPACPI_ERR "Failed to create ALSA mute control: %d\n",
+                       rc);
+               goto err_exit;
        }
        data->ctl_mute_id = &ctl_mute->id;
 
        snd_card_set_dev(card, &tpacpi_pdev->dev);
        rc = snd_card_register(card);
-
-err_out:
        if (rc < 0) {
-               snd_card_free(card);
-               card = NULL;
+               printk(TPACPI_ERR "Failed to register ALSA card: %d\n", rc);
+               goto err_exit;
        }
 
        alsa_card = card;
-       return rc;
+       return 0;
+
+err_exit:
+       snd_card_free(card);
+       return 1;
 }
 
 #define TPACPI_VOL_Q_MUTEONLY  0x0001  /* Mute-only control available */
@@ -7016,6 +7023,28 @@ static struct ibm_struct volume_driver_data = {
        .shutdown = volume_shutdown,
 };
 
+#else /* !CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */
+
+#define alsa_card NULL
+
+static void inline volume_alsa_notify_change(void)
+{
+}
+
+static int __init volume_init(struct ibm_init_struct *iibm)
+{
+       printk(TPACPI_INFO
+               "volume: disabled as there is no ALSA support in this kernel\n");
+
+       return 1;
+}
+
+static struct ibm_struct volume_driver_data = {
+       .name = "volume",
+};
+
+#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */
+
 /*************************************************************************
  * Fan subdriver
  */
@@ -8738,6 +8767,7 @@ MODULE_PARM_DESC(hotkey_report_mode,
                 "used for backwards compatibility with userspace, "
                 "see documentation");
 
+#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
 module_param_named(volume_mode, volume_mode, uint, 0444);
 MODULE_PARM_DESC(volume_mode,
                 "Selects volume control strategy: "
@@ -8760,6 +8790,7 @@ module_param_named(id, alsa_id, charp, 0444);
 MODULE_PARM_DESC(id, "ALSA id for the ACPI EC Mixer");
 module_param_named(enable, alsa_enable, bool, 0444);
 MODULE_PARM_DESC(enable, "Enable the ALSA interface for the ACPI EC Mixer");
+#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */
 
 #define TPACPI_PARAM(feature) \
        module_param_call(feature, set_ibm_param, NULL, NULL, 0); \