aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/thinkpad_acpi.c130
-rw-r--r--drivers/misc/thinkpad_acpi.h20
2 files changed, 108 insertions, 42 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 344eb551c443..a77368f90181 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -681,6 +681,8 @@ static struct ibm_struct hotkey_driver_data = {
681 681
682static int __init bluetooth_init(struct ibm_init_struct *iibm) 682static int __init bluetooth_init(struct ibm_init_struct *iibm)
683{ 683{
684 int status = 0;
685
684 vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n"); 686 vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
685 687
686 IBM_ACPIHANDLE_INIT(hkey); 688 IBM_ACPIHANDLE_INIT(hkey);
@@ -688,36 +690,65 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
688 /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 690 /* bluetooth not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
689 G4x, R30, R31, R40e, R50e, T20-22, X20-21 */ 691 G4x, R30, R31, R40e, R50e, T20-22, X20-21 */
690 tp_features.bluetooth = hkey_handle && 692 tp_features.bluetooth = hkey_handle &&
691 acpi_evalf(hkey_handle, NULL, "GBDC", "qv"); 693 acpi_evalf(hkey_handle, &status, "GBDC", "qd");
692 694
693 vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s\n", 695 vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
694 str_supported(tp_features.bluetooth)); 696 str_supported(tp_features.bluetooth),
697 status);
698
699 if (tp_features.bluetooth &&
700 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
701 /* no bluetooth hardware present in system */
702 tp_features.bluetooth = 0;
703 dbg_printk(TPACPI_DBG_INIT,
704 "bluetooth hardware not installed\n");
705 }
695 706
696 return (tp_features.bluetooth)? 0 : 1; 707 return (tp_features.bluetooth)? 0 : 1;
697} 708}
698 709
699static int bluetooth_status(void) 710static int bluetooth_get_radiosw(void)
700{ 711{
701 int status; 712 int status;
702 713
703 if (!tp_features.bluetooth || 714 if (!tp_features.bluetooth)
704 !acpi_evalf(hkey_handle, &status, "GBDC", "d")) 715 return -ENODEV;
705 status = 0;
706 716
707 return status; 717 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
718 return -EIO;
719
720 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0);
721}
722
723static int bluetooth_set_radiosw(int radio_on)
724{
725 int status;
726
727 if (!tp_features.bluetooth)
728 return -ENODEV;
729
730 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
731 return -EIO;
732 if (radio_on)
733 status |= TP_ACPI_BLUETOOTH_RADIOSSW;
734 else
735 status &= ~TP_ACPI_BLUETOOTH_RADIOSSW;
736 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
737 return -EIO;
738
739 return 0;
708} 740}
709 741
710static int bluetooth_read(char *p) 742static int bluetooth_read(char *p)
711{ 743{
712 int len = 0; 744 int len = 0;
713 int status = bluetooth_status(); 745 int status = bluetooth_get_radiosw();
714 746
715 if (!tp_features.bluetooth) 747 if (!tp_features.bluetooth)
716 len += sprintf(p + len, "status:\t\tnot supported\n"); 748 len += sprintf(p + len, "status:\t\tnot supported\n");
717 else if (!(status & 1))
718 len += sprintf(p + len, "status:\t\tnot installed\n");
719 else { 749 else {
720 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 1)); 750 len += sprintf(p + len, "status:\t\t%s\n",
751 (status)? "enabled" : "disabled");
721 len += sprintf(p + len, "commands:\tenable, disable\n"); 752 len += sprintf(p + len, "commands:\tenable, disable\n");
722 } 753 }
723 754
@@ -726,26 +757,20 @@ static int bluetooth_read(char *p)
726 757
727static int bluetooth_write(char *buf) 758static int bluetooth_write(char *buf)
728{ 759{
729 int status = bluetooth_status();
730 char *cmd; 760 char *cmd;
731 int do_cmd = 0;
732 761
733 if (!tp_features.bluetooth) 762 if (!tp_features.bluetooth)
734 return -ENODEV; 763 return -ENODEV;
735 764
736 while ((cmd = next_cmd(&buf))) { 765 while ((cmd = next_cmd(&buf))) {
737 if (strlencmp(cmd, "enable") == 0) { 766 if (strlencmp(cmd, "enable") == 0) {
738 status |= 2; 767 bluetooth_set_radiosw(1);
739 } else if (strlencmp(cmd, "disable") == 0) { 768 } else if (strlencmp(cmd, "disable") == 0) {
740 status &= ~2; 769 bluetooth_set_radiosw(0);
741 } else 770 } else
742 return -EINVAL; 771 return -EINVAL;
743 do_cmd = 1;
744 } 772 }
745 773
746 if (do_cmd && !acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
747 return -EIO;
748
749 return 0; 774 return 0;
750} 775}
751 776
@@ -761,41 +786,72 @@ static struct ibm_struct bluetooth_driver_data = {
761 786
762static int __init wan_init(struct ibm_init_struct *iibm) 787static int __init wan_init(struct ibm_init_struct *iibm)
763{ 788{
789 int status = 0;
790
764 vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n"); 791 vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
765 792
766 IBM_ACPIHANDLE_INIT(hkey); 793 IBM_ACPIHANDLE_INIT(hkey);
767 794
768 tp_features.wan = hkey_handle && 795 tp_features.wan = hkey_handle &&
769 acpi_evalf(hkey_handle, NULL, "GWAN", "qv"); 796 acpi_evalf(hkey_handle, &status, "GWAN", "qd");
770 797
771 vdbg_printk(TPACPI_DBG_INIT, "wan is %s\n", 798 vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
772 str_supported(tp_features.wan)); 799 str_supported(tp_features.wan),
800 status);
801
802 if (tp_features.wan &&
803 !(status & TP_ACPI_WANCARD_HWPRESENT)) {
804 /* no wan hardware present in system */
805 tp_features.wan = 0;
806 dbg_printk(TPACPI_DBG_INIT,
807 "wan hardware not installed\n");
808 }
773 809
774 return (tp_features.wan)? 0 : 1; 810 return (tp_features.wan)? 0 : 1;
775} 811}
776 812
777static int wan_status(void) 813static int wan_get_radiosw(void)
778{ 814{
779 int status; 815 int status;
780 816
781 if (!tp_features.wan || 817 if (!tp_features.wan)
782 !acpi_evalf(hkey_handle, &status, "GWAN", "d")) 818 return -ENODEV;
783 status = 0;
784 819
785 return status; 820 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
821 return -EIO;
822
823 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0);
824}
825
826static int wan_set_radiosw(int radio_on)
827{
828 int status;
829
830 if (!tp_features.wan)
831 return -ENODEV;
832
833 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
834 return -EIO;
835 if (radio_on)
836 status |= TP_ACPI_WANCARD_RADIOSSW;
837 else
838 status &= ~TP_ACPI_WANCARD_RADIOSSW;
839 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
840 return -EIO;
841
842 return 0;
786} 843}
787 844
788static int wan_read(char *p) 845static int wan_read(char *p)
789{ 846{
790 int len = 0; 847 int len = 0;
791 int status = wan_status(); 848 int status = wan_get_radiosw();
792 849
793 if (!tp_features.wan) 850 if (!tp_features.wan)
794 len += sprintf(p + len, "status:\t\tnot supported\n"); 851 len += sprintf(p + len, "status:\t\tnot supported\n");
795 else if (!(status & 1))
796 len += sprintf(p + len, "status:\t\tnot installed\n");
797 else { 852 else {
798 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 1)); 853 len += sprintf(p + len, "status:\t\t%s\n",
854 (status)? "enabled" : "disabled");
799 len += sprintf(p + len, "commands:\tenable, disable\n"); 855 len += sprintf(p + len, "commands:\tenable, disable\n");
800 } 856 }
801 857
@@ -804,26 +860,20 @@ static int wan_read(char *p)
804 860
805static int wan_write(char *buf) 861static int wan_write(char *buf)
806{ 862{
807 int status = wan_status();
808 char *cmd; 863 char *cmd;
809 int do_cmd = 0;
810 864
811 if (!tp_features.wan) 865 if (!tp_features.wan)
812 return -ENODEV; 866 return -ENODEV;
813 867
814 while ((cmd = next_cmd(&buf))) { 868 while ((cmd = next_cmd(&buf))) {
815 if (strlencmp(cmd, "enable") == 0) { 869 if (strlencmp(cmd, "enable") == 0) {
816 status |= 2; 870 wan_set_radiosw(1);
817 } else if (strlencmp(cmd, "disable") == 0) { 871 } else if (strlencmp(cmd, "disable") == 0) {
818 status &= ~2; 872 wan_set_radiosw(0);
819 } else 873 } else
820 return -EINVAL; 874 return -EINVAL;
821 do_cmd = 1;
822 } 875 }
823 876
824 if (do_cmd && !acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
825 return -EIO;
826
827 return 0; 877 return 0;
828} 878}
829 879
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 1b4cd167ebd2..e06bad5c8fe4 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -241,8 +241,16 @@ static int beep_write(char *buf);
241 * Bluetooth subdriver 241 * Bluetooth subdriver
242 */ 242 */
243 243
244enum {
245 /* ACPI GBDC/SBDC bits */
246 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */
247 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */
248 TP_ACPI_BLUETOOTH_UNK = 0x04, /* unknown function */
249};
250
244static int bluetooth_init(struct ibm_init_struct *iibm); 251static int bluetooth_init(struct ibm_init_struct *iibm);
245static int bluetooth_status(void); 252static int bluetooth_get_radiosw(void);
253static int bluetooth_set_radiosw(int radio_on);
246static int bluetooth_read(char *p); 254static int bluetooth_read(char *p);
247static int bluetooth_write(char *buf); 255static int bluetooth_write(char *buf);
248 256
@@ -467,8 +475,16 @@ static int volume_write(char *buf);
467 * Wan subdriver 475 * Wan subdriver
468 */ 476 */
469 477
478enum {
479 /* ACPI GWAN/SWAN bits */
480 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */
481 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */
482 TP_ACPI_WANCARD_UNK = 0x04, /* unknown function */
483};
484
470static int wan_init(struct ibm_init_struct *iibm); 485static int wan_init(struct ibm_init_struct *iibm);
471static int wan_status(void); 486static int wan_get_radiosw(void);
487static int wan_set_radiosw(int radio_on);
472static int wan_read(char *p); 488static int wan_read(char *p);
473static int wan_write(char *buf); 489static int wan_write(char *buf);
474 490