├── License.md ├── README.md ├── VoodooPS2Controller.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── ahmad.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings ├── xcshareddata │ └── xcschemes │ │ ├── All Kext.xcscheme │ │ ├── All.xcscheme │ │ ├── VoodooPS2Controller.xcscheme │ │ ├── VoodooPS2Keyboard.xcscheme │ │ └── VoodooPS2Trackpad.xcscheme └── xcuserdata │ └── ahmad.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── VoodooPS2Controller ├── AppleACPIPS2Nub.cpp ├── AppleACPIPS2Nub.h ├── ApplePS2Device.cpp ├── ApplePS2Device.h ├── ApplePS2KeyboardDevice.cpp ├── ApplePS2KeyboardDevice.h ├── ApplePS2MouseDevice.cpp ├── ApplePS2MouseDevice.h ├── VoodooPS2Controller-Info.plist ├── VoodooPS2Controller-Prefix.pch ├── VoodooPS2Controller.cpp ├── VoodooPS2Controller.h └── en.lproj │ └── InfoPlist.strings ├── VoodooPS2Keyboard ├── ApplePS2ToADBMap.h ├── VoodooPS2Keyboard-Breakless-Info.plist ├── VoodooPS2Keyboard-Info.plist ├── VoodooPS2Keyboard-Prefix.pch ├── VoodooPS2Keyboard-RemapFN-Info.plist ├── VoodooPS2Keyboard.cpp ├── VoodooPS2Keyboard.h └── en.lproj │ └── InfoPlist.strings ├── VoodooPS2Trackpad ├── Decay.h ├── VoodooPS2TouchPadBase.cpp ├── VoodooPS2TouchPadBase.h ├── VoodooPS2Trackpad-Info.plist ├── VoodooPS2Trackpad-Prefix.pch ├── alps.cpp ├── alps.h └── en.lproj │ └── InfoPlist.strings ├── makefile ├── new_kext.cpp └── new_kext.h /License.md: -------------------------------------------------------------------------------- 1 | ## APPLE PUBLIC SOURCE LICENSE 2 | ## Version 2.0 - August 6, 2003 3 | 4 | Please read this License carefully before downloading this software. By downloading or using this software, you are agreeing to be bound by the terms of this License. If you do not or cannot agree to the terms of this License, please do not download or use the software. 5 | 6 | 1\. General; Definitions. This License applies to any program or other work which Apple Computer, Inc. ("Apple") makes publicly available and which contains a notice placed by Apple identifying such program or work as "Original Code" and stating that it is subject to the terms of this Apple Public Source License version 2.0 ("License"). As used in this License: 7 | 8 | 1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is the grantor of rights, (i) claims of patents that are now or hereafter acquired, owned by or assigned to Apple and (ii) that cover subject matter contained in the Original Code, but only to the extent necessary to use, reproduce and/or distribute the Original Code without infringement; and (b) in the case where You are the grantor of rights, (i) claims of patents that are now or hereafter acquired, owned by or assigned to You and (ii) that cover subject matter in Your Modifications, taken alone or in combination with Original Code. 9 | 10 | 1.2 "Contributor" means any person or entity that creates or contributes to the creation of Modifications. 11 | 12 | 1.3 "Covered Code" means the Original Code, Modifications, the combination of Original Code and any Modifications, and/or any respective portions thereof. 13 | 14 | 1.4 "Externally Deploy" means: (a) to sublicense, distribute or otherwise make Covered Code available, directly or indirectly, to anyone other than You; and/or (b) to use Covered Code, alone or as part of a Larger Work, in any way to provide a service, including but not limited to delivery of content, through electronic communication with a client other than You. 15 | 16 | 1.5 "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. 17 | 18 | 1.6 "Modifications" mean any addition to, deletion from, and/or change to, the substance and/or structure of the Original Code, any previous Modifications, the combination of Original Code and any previous Modifications, and/or any respective portions thereof. When code is released as a series of files, a Modification is: (a) any addition to or deletion from the contents of a file containing Covered Code; and/or (b) any new file or other representation of computer program statements that contains any part of Covered Code. 19 | 20 | 1.7 "Original Code" means (a) the Source Code of a program or other work as originally made available by Apple under this License, including the Source Code of any updates or upgrades to such programs or works made available by Apple under this License, and that has been expressly identified by Apple as such in the header file(s) of such work; and (b) the object code compiled from such Source Code and originally made available by Apple under this License. 21 | 22 | 1.8 "Source Code" means the human readable form of a program or other work that is suitable for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an executable (object code). 23 | 24 | 1.9 "You" or "Your" means an individual or a legal entity exercising rights under this License. For legal entities, "You" or "Your" includes any entity which controls, is controlled by, or is under common control with, You, where "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of fifty percent (50%) or more of the outstanding shares or beneficial ownership of such entity. 25 | 26 | 2\. Permitted Uses; Conditions & Restrictions. Subject to the terms and conditions of this License, Apple hereby grants You, effective on the date You accept this License and download the Original Code, a world-wide, royalty-free, non-exclusive license, to the extent of Apple's Applicable Patent Rights and copyrights covering the Original Code, to do the following: 27 | 28 | 2.1 Unmodified Code. You may use, reproduce, display, perform, internally distribute within Your organization, and Externally Deploy verbatim, unmodified copies of the Original Code, for commercial or non-commercial purposes, provided that in each instance: 29 | 30 | (a) You must retain and reproduce in all copies of Original Code the copyright and other proprietary notices and disclaimers of Apple as they appear in the Original Code, and keep intact all notices in the Original Code that refer to this License; and 31 | 32 | (b) You must include a copy of this License with every copy of Source Code of Covered Code and documentation You distribute or Externally Deploy, and You may not offer or impose any terms on such Source Code that alter or restrict this License or the recipients' rights hereunder, except as permitted under Section 6. 33 | 34 | 2.2 Modified Code. You may modify Covered Code and use, reproduce, display, perform, internally distribute within Your organization, and Externally Deploy Your Modifications and Covered Code, for commercial or non-commercial purposes, provided that in each instance You also meet all of these conditions: 35 | 36 | (a) You must satisfy all the conditions of Section 2.1 with respect to the Source Code of the Covered Code; 37 | 38 | (b) You must duplicate, to the extent it does not already exist, the notice in Exhibit A in each file of the Source Code of all Your Modifications, and cause the modified files to carry prominent notices stating that You changed the files and the date of any change; and 39 | 40 | (c) If You Externally Deploy Your Modifications, You must make Source Code of all Your Externally Deployed Modifications either available to those to whom You have Externally Deployed Your Modifications, or publicly available. Source Code of Your Externally Deployed Modifications must be released under the terms set forth in this License, including the license grants set forth in Section 3 below, for as long as you Externally Deploy the Covered Code or twelve (12) months from the date of initial External Deployment, whichever is longer. You should preferably distribute the Source Code of Your Externally Deployed Modifications electronically (e.g. download from a web site). 41 | 42 | 2.3 Distribution of Executable Versions. In addition, if You Externally Deploy Covered Code (Original Code and/or Modifications) in object code, executable form only, You must include a prominent notice, in the code itself as well as in related documentation, stating that Source Code of the Covered Code is available under the terms of this License with information on how and where to obtain such Source Code. 43 | 44 | 2.4 Third Party Rights. You expressly acknowledge and agree that although Apple and each Contributor grants the licenses to their respective portions of the Covered Code set forth herein, no assurances are provided by Apple or any Contributor that the Covered Code does not infringe the patent or other intellectual property rights of any other entity. Apple and each Contributor disclaim any liability to You for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, You hereby assume sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow You to distribute the Covered Code, it is Your responsibility to acquire that license before distributing the Covered Code. 45 | 46 | 3\. Your Grants. In consideration of, and as a condition to, the licenses granted to You under this License, You hereby grant to any person or entity receiving or distributing Covered Code under this License a non-exclusive, royalty-free, perpetual, irrevocable license, under Your Applicable Patent Rights and other intellectual property rights (other than patent) owned or controlled by You, to use, reproduce, display, perform, modify, sublicense, distribute and Externally Deploy Your Modifications of the same scope and extent as Apple's licenses under Sections 2.1 and 2.2 above. 47 | 48 | 4\. Larger Works. You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In each such instance, You must make sure the requirements of this License are fulfilled for the Covered Code or any portion thereof. 49 | 50 | 5\. Limitations on Patent License. Except as expressly stated in Section 2, no other patent rights, express or implied, are granted by Apple herein. Modifications and/or Larger Works may require additional patent licenses from Apple which Apple may grant in its sole discretion. 51 | 52 | 6\. Additional Terms. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the scope of the license granted herein ("Additional Terms") to one or more recipients of Covered Code. However, You may do so only on Your own behalf and as Your sole responsibility, and not on behalf of Apple or any Contributor. You must obtain the recipient's agreement that any such Additional Terms are offered by You alone, and You hereby agree to indemnify, defend and hold Apple and every Contributor harmless for any liability incurred by or claims asserted against Apple or such Contributor by reason of any such Additional Terms. 53 | 54 | 7\. Versions of the License. Apple may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Once Original Code has been published under a particular version of this License, You may continue to use it under the terms of that version. You may also choose to use such Original Code under the terms of any subsequent version of this License published by Apple. No one other than Apple has the right to modify the terms applicable to Covered Code created under this License. 55 | 56 | 8\. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in part pre-release, untested, or not fully tested works. The Covered Code may contain errors that could cause failures or loss of data, and may be incomplete or contain inaccuracies. You expressly acknowledge and agree that use of the Covered Code, or any portion thereof, is at Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS, THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY. You acknowledge that the Covered Code is not intended for use in the operation of nuclear facilities, aircraft navigation, communication systems, or air traffic control machines in which case the failure of the Covered Code could lead to death, personal injury, or severe physical or environmental damage. 57 | 58 | 9\. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU. In no event shall Apple's total liability to You for all damages (other than as may be required by applicable law) under this License exceed the amount of fifty dollars ($50.00). 59 | 60 | 10\. Trademarks. This License does not grant any rights to use the trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS", "QuickTime", "QuickTime Streaming Server" or any other trademarks, service marks, logos or trade names belonging to Apple (collectively "Apple Marks") or to any trademark, service mark, logo or trade name belonging to any Contributor. You agree not to use any Apple Marks in or as part of the name of products derived from the Original Code or to endorse or promote products derived from the Original Code other than as expressly permitted by and in strict compliance at all times with Apple's third party trademark usage guidelines which are posted at http://www.apple.com/legal/guidelinesfor3rdparties.html. 61 | 62 | 11\. Ownership. Subject to the licenses granted under this License, each Contributor retains all rights, title and interest in and to any Modifications made by such Contributor. Apple retains all rights, title and interest in and to the Original Code and any Modifications made by or on behalf of Apple ("Apple Modifications"), and such Apple Modifications will not be automatically subject to this License. Apple may, at its sole discretion, choose to license such Apple Modifications under this License, or on different terms from those contained in this License or may choose not to license them at all. 63 | 64 | 12\. Termination. 65 | 66 | 12.1 Termination. This License and the rights granted hereunder will terminate: 67 | 68 | (a) automatically without notice from Apple if You fail to comply with any term(s) of this License and fail to cure such breach within 30 days of becoming aware of such breach; 69 | 70 | (b) immediately in the event of the circumstances described in Section 13.5(b); or 71 | 72 | (c) automatically without notice from Apple if You, at any time during the term of this License, commence an action for patent infringement against Apple; provided that Apple did not first commence an action for patent infringement against You in that instance. 73 | 74 | 12.2 Effect of Termination. Upon termination, You agree to immediately stop any further use, reproduction, modification, sublicensing and distribution of the Covered Code. All sublicenses to the Covered Code which have been properly granted prior to termination shall survive any termination of this License. Provisions which, by their nature, should remain in effect beyond the termination of this License shall survive, including but not limited to Sections 3, 5, 8, 9, 10, 11, 12.2 and 13. No party will be liable to any other for compensation, indemnity or damages of any sort solely as a result of terminating this License in accordance with its terms, and termination of this License will be without prejudice to any other right or remedy of any party. 75 | 76 | 13\. Miscellaneous. 77 | 78 | 13.1 Government End Users. The Covered Code is a "commercial item" as defined in FAR 2.101. Government software and technical data rights in the Covered Code include only those rights customarily provided to the public as defined in this License. This customary commercial license in technical data and software is provided in accordance with FAR 12.211 (Technical Data) and 12.212 (Computer Software) and, for Department of Defense purchases, DFAR 252.227-7015 (Technical Data -- Commercial Items) and 227.7202-3 (Rights in Commercial Computer Software or Computer Software Documentation). Accordingly, all U.S. Government End Users acquire Covered Code with only those rights set forth herein. 79 | 80 | 13.2 Relationship of Parties. This License will not be construed as creating an agency, partnership, joint venture or any other form of legal association between or among You, Apple or any Contributor, and You will not represent to the contrary, whether expressly, by implication, appearance or otherwise. 81 | 82 | 13.3 Independent Development. Nothing in this License will impair Apple's right to acquire, license, develop, have others develop for it, market and/or distribute technology or products that perform the same or similar functions as, or otherwise compete with, Modifications, Larger Works, technology or products that You may develop, produce, market or distribute. 83 | 84 | 13.4 Waiver; Construction. Failure by Apple or any Contributor to enforce any provision of this License will not be deemed a waiver of future enforcement of that or any other provision. Any law or regulation which provides that the language of a contract shall be construed against the drafter will not apply to this License. 85 | 86 | 13.5 Severability. (a) If for any reason a court of competent jurisdiction finds any provision of this License, or portion thereof, to be unenforceable, that provision of the License will be enforced to the maximum extent permissible so as to effect the economic benefits and intent of the parties, and the remainder of this License will continue in full force and effect. (b) Notwithstanding the foregoing, if applicable law prohibits or restricts You from fully and/or specifically complying with Sections 2 and/or 3 or prevents the enforceability of either of those Sections, this License will immediately terminate and You must immediately discontinue any use of the Covered Code and destroy all copies of it that are in your possession or control. 87 | 88 | 13.6 Dispute Resolution. Any litigation or other dispute resolution between You and Apple relating to this License shall take place in the Northern District of California, and You and Apple hereby consent to the personal jurisdiction of, and venue in, the state and federal courts within that District with respect to this License. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. 89 | 90 | 13.7 Entire Agreement; Governing Law. This License constitutes the entire agreement between the parties with respect to the subject matter hereof. This License shall be governed by the laws of the United States and the State of California, except that body of California law concerning conflicts of law. 91 | 92 | Where You are located in the province of Quebec, Canada, the following clause applies: The parties hereby confirm that they have requested that this License and all related documents be drafted in English. Les parties ont exige que le present contrat et tous les documents connexes soient rediges en anglais. 93 | 94 | EXHIBIT A. 95 | 96 | "Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. 97 | 98 | This file contains Original Code and/or Modifications of Original Code as defined in and that are subject to the Apple Public Source License Version 2.0 (the 'License'). You may not use this file except in compliance with the License. Please obtain a copy of the License at http://www.opensource.apple.com/apsl/ and read it before using this file. 99 | 100 | The Original Code and all software distributed under the License are distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the specific language governing rights and limitations under the License." 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OS-X-ALPS-DRIVER 2 | 3 | This driver is based on Rehabman's VoodooPS2 driver for macOS, Linux 4.7, and bpedman's earlier work. V7 support was ported by coolstarorg. 4 | 5 | The aim of this driver is to improve the usability of ALPS TouchPads in macOS. 6 | 7 | Driver Features: 8 | 9 | Supports ALPS hardware versions V1-V5, V7, V8 10 | Supports Mac OS 10.6 to 10.13 and up 11 | 1-finger tapping. 12 | Side (edge) scrolling (Vertical with inertia, and Horizontal). 13 | 2-finger tap for right click. 14 | 2-finger scrolling (vertical and horizontal with inertia). 15 | 3 and 4-finger gestures (V3+, check the log to find out your hw version). 16 | Pointer acceleration and smoothing. 17 | Trackstick (movement and scrolling). 18 | Changes: 19 | 20 | Touchpad initialization, packet decoding and processing updated Linux 4.7 21 | Bitmap processing overhauled. Can now provide coordinates for 2 fingers simultaneously. 22 | Added new device ids for better compatibility. 23 | Remove hardcoded variables allowing userspace (plist) settings to apply. 24 | Painstakingly optimized default settings to provide the best possible experience. 25 | Improve pointer motion calculation, mode switching,… etc. 26 | Lots of code cleanups, refactoring. 27 | Clean up the IOLog. 28 | 29 | Slice: 30 | Added multimedia keys. Improve keyboard handling 31 | -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/project.xcworkspace/xcuserdata/ahmad.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SergeySlice/VoodooPS2-for-ALPS/241dca08ae09a172ded3c345e455f68c979d7e67/VoodooPS2Controller.xcodeproj/project.xcworkspace/xcuserdata/ahmad.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/project.xcworkspace/xcuserdata/ahmad.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseAppPreferences 7 | CustomBuildLocationType 8 | RelativeToDerivedData 9 | DerivedDataCustomLocation 10 | DerivedData 11 | DerivedDataLocationStyle 12 | WorkspaceRelativePath 13 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 14 | 15 | IssueFilterStyle 16 | ShowActiveSchemeOnly 17 | LiveSourceIssuesEnabled 18 | 19 | SnapshotAutomaticallyBeforeSignificantChanges 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/xcshareddata/xcschemes/All Kext.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 57 | 63 | 64 | 65 | 66 | 67 | 72 | 73 | 74 | 75 | 76 | 77 | 87 | 88 | 94 | 95 | 96 | 97 | 98 | 99 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/xcshareddata/xcschemes/All.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 60 | 61 | 67 | 68 | 69 | 70 | 71 | 72 | 82 | 83 | 89 | 90 | 91 | 92 | 93 | 94 | 100 | 101 | 107 | 108 | 109 | 110 | 112 | 113 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/xcshareddata/xcschemes/VoodooPS2Controller.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 57 | 63 | 64 | 65 | 71 | 77 | 78 | 79 | 85 | 91 | 92 | 93 | 94 | 95 | 100 | 101 | 102 | 103 | 104 | 105 | 115 | 116 | 122 | 123 | 124 | 125 | 126 | 127 | 133 | 134 | 136 | 137 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/xcshareddata/xcschemes/VoodooPS2Keyboard.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/xcshareddata/xcschemes/VoodooPS2Trackpad.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /VoodooPS2Controller.xcodeproj/xcuserdata/ahmad.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SuppressBuildableAutocreation 6 | 7 | 84167812161B55B2002C60E6 8 | 9 | primary 10 | 11 | 12 | 8416782C161B5613002C60E6 13 | 14 | primary 15 | 16 | 17 | 84167840161B56A2002C60E6 18 | 19 | primary 20 | 21 | 22 | 84167854161B56C4002C60E6 23 | 24 | primary 25 | 26 | 27 | 84C337991698B693009B8177 28 | 29 | primary 30 | 31 | 32 | 84F424E1161B59E500777765 33 | 34 | primary 35 | 36 | 37 | 84F424FA161B5A4900777765 38 | 39 | primary 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /VoodooPS2Controller/AppleACPIPS2Nub.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /*! @file AppleACPIPS2Nub.cpp 24 | @abstract AppleACPIPS2Nub class implementation 25 | @discussion 26 | Implements the ACPI PS/2 nub for ApplePS2Controller.kext. 27 | Reverse-engineered from the Darwin 8 binary ACPI kext. 28 | Copyright 2007 David Elliott 29 | */ 30 | 31 | #include "AppleACPIPS2Nub.h" 32 | 33 | #if 0 34 | #define DEBUG_LOG(args...) IOLog(args) 35 | #else 36 | #define DEBUG_LOG(args...) 37 | #endif 38 | 39 | static IOPMPowerState myTwoStates[2] = { 40 | {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 41 | {1, kIOPMPowerOn, kIOPMPowerOn, kIOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0} 42 | }; 43 | 44 | OSDefineMetaClassAndStructors(AppleACPIPS2Nub, IOPlatformDevice); 45 | 46 | // We could simply ask for the PE rather than importing the global 47 | // from AppleACPIPlatformExpert.kext 48 | // extern IOPlatformExpert *gAppleACPIPlatformExpert; 49 | 50 | bool AppleACPIPS2Nub::start(IOService *provider) 51 | { 52 | if (!super::start(provider)) 53 | return false; 54 | 55 | DEBUG_LOG("AppleACPIPS2Nub::start: provider=%p\n", provider); 56 | 57 | /* Initialize our interrupt controller/specifier i-vars */ 58 | m_interruptControllers = OSArray::withCapacity(2); 59 | m_interruptSpecifiers = OSArray::withCapacity(2); 60 | if(m_interruptControllers == NULL || m_interruptSpecifiers == NULL) 61 | return false; 62 | 63 | /* Merge in the keyboard (primary) provider interrupt properties */ 64 | mergeInterruptProperties(provider, LEGACY_KEYBOARD_IRQ); 65 | 66 | /* Initialize and register our power management properties */ 67 | PMinit(); 68 | registerPowerDriver(this, myTwoStates, 2); 69 | provider->joinPMtree(this); 70 | 71 | /* Find the mouse provider */ 72 | m_mouseProvider = findMouseDevice(); 73 | if(m_mouseProvider != NULL) 74 | { 75 | DEBUG_LOG("AppleACPIPS2Nub::start: Found mouse PNP device\n"); 76 | if(attach(m_mouseProvider)) 77 | { 78 | mergeInterruptProperties(m_mouseProvider, LEGACY_MOUSE_IRQ); 79 | if(m_mouseProvider->inPlane(gIOPowerPlane)) 80 | { 81 | m_mouseProvider->joinPMtree(this); 82 | } 83 | } 84 | } 85 | 86 | /* Set our interrupt properties in the IO registry */ 87 | if(m_interruptControllers->getCount() != 0 && m_interruptSpecifiers->getCount() != 0) 88 | { 89 | setProperty(gIOInterruptControllersKey, m_interruptControllers); 90 | setProperty(gIOInterruptSpecifiersKey, m_interruptSpecifiers); 91 | } 92 | 93 | /* Release the arrays we allocated. Our properties dictionary has them retained */ 94 | m_interruptControllers->release(); 95 | m_interruptControllers = NULL; 96 | m_interruptSpecifiers->release(); 97 | m_interruptSpecifiers = NULL; 98 | 99 | /* Make ourselves the ps2controller nub and register so ApplePS2Controller can find us. */ 100 | setName("ps2controller"); 101 | registerService(); 102 | 103 | DEBUG_LOG("AppleACPIPS2Nub::start: startup complete\n"); 104 | 105 | return true; 106 | } 107 | 108 | IOService *AppleACPIPS2Nub::findMouseDevice() 109 | { 110 | OSObject *prop = getProperty("MouseNameMatch"); 111 | /* Search from the root of the ACPI plane for the mouse PNP nub */ 112 | IORegistryIterator *i = IORegistryIterator::iterateOver(gIOACPIPlane, kIORegistryIterateRecursively); 113 | IORegistryEntry *entry; 114 | if(i != NULL) 115 | { 116 | while((entry = i->getNextObject())) 117 | { 118 | if(entry->compareNames(prop)) 119 | break; 120 | } 121 | i->release(); 122 | } 123 | else 124 | entry = NULL; 125 | return OSDynamicCast(IOService, entry); 126 | } 127 | 128 | void AppleACPIPS2Nub::mergeInterruptProperties(IOService *pnpProvider, long) 129 | { 130 | /* Get the interrupt controllers/specifiers arrays from the provider, and make sure they 131 | * exist and contain at least one entry. We assume they contain exactly one entry. 132 | */ 133 | OSArray *controllers = OSDynamicCast(OSArray,pnpProvider->getProperty(gIOInterruptControllersKey)); 134 | OSArray *specifiers = OSDynamicCast(OSArray,pnpProvider->getProperty(gIOInterruptSpecifiersKey)); 135 | if(controllers == NULL || specifiers == NULL) 136 | return; 137 | if(controllers->getCount() == 0 || specifiers->getCount() == 0) 138 | return; 139 | 140 | /* Append the first object of each array into our own respective array */ 141 | m_interruptControllers->setObject(controllers->getObject(0)); 142 | m_interruptSpecifiers->setObject(specifiers->getObject(0)); 143 | } 144 | 145 | IOReturn AppleACPIPS2Nub::registerInterrupt(int source, OSObject *target, IOInterruptAction handler, void *refCon) 146 | { 147 | if(source == LEGACY_KEYBOARD_IRQ) 148 | return super::registerInterrupt(0, target, handler, refCon); 149 | else if(source == LEGACY_MOUSE_IRQ) 150 | return super::registerInterrupt(1, target, handler, refCon); 151 | else 152 | return kIOReturnBadArgument; 153 | } 154 | 155 | IOReturn AppleACPIPS2Nub::unregisterInterrupt(int source) 156 | { 157 | if(source == LEGACY_KEYBOARD_IRQ) 158 | return super::unregisterInterrupt(0); 159 | else if(source == LEGACY_MOUSE_IRQ) 160 | return super::unregisterInterrupt(1); 161 | else 162 | return kIOReturnBadArgument; 163 | } 164 | 165 | IOReturn AppleACPIPS2Nub::getInterruptType(int source, int *interruptType) 166 | { 167 | if(source == LEGACY_KEYBOARD_IRQ) 168 | return super::getInterruptType(0, interruptType); 169 | else if(source == LEGACY_MOUSE_IRQ) 170 | return super::getInterruptType(1, interruptType); 171 | else 172 | return kIOReturnBadArgument; 173 | } 174 | 175 | IOReturn AppleACPIPS2Nub::enableInterrupt(int source) 176 | { 177 | if(source == LEGACY_KEYBOARD_IRQ) 178 | return super::enableInterrupt(0); 179 | else if(source == LEGACY_MOUSE_IRQ) 180 | return super::enableInterrupt(1); 181 | else 182 | return kIOReturnBadArgument; 183 | } 184 | 185 | IOReturn AppleACPIPS2Nub::disableInterrupt(int source) 186 | { 187 | if(source == LEGACY_KEYBOARD_IRQ) 188 | return super::disableInterrupt(0); 189 | else if(source == LEGACY_MOUSE_IRQ) 190 | return super::disableInterrupt(1); 191 | else 192 | return kIOReturnBadArgument; 193 | } 194 | 195 | bool AppleACPIPS2Nub::compareName( OSString * name, OSString ** matched ) const 196 | { 197 | // return gAppleACPIPlatformExpert->compareNubName( this, name, matched ); 198 | return( this->IORegistryEntry::compareName( name, matched )); 199 | } 200 | 201 | IOReturn AppleACPIPS2Nub::getResources( void ) 202 | { 203 | // return gAppleACPIPlatformExpert->getNubResources(this); 204 | return( kIOReturnSuccess ); 205 | } 206 | 207 | IOReturn AppleACPIPS2Nub::message( UInt32 type, IOService *provider, void *argument ) 208 | { 209 | ////DEBUG_LOG("AppleACPIPS2Nub::message: type=%x, provider=%p, argument=%p\n", type, provider, argument); 210 | 211 | // forward to all interested sub-entries 212 | IORegistryIterator *i = IORegistryIterator::iterateOver(this, gIOServicePlane, kIORegistryIterateRecursively); 213 | IORegistryEntry *entry; 214 | if(i != NULL) 215 | { 216 | while((entry = i->getNextObject())) 217 | { 218 | IOService* service = OSDynamicCast(IOService, entry); 219 | if(service != NULL && service->getProperty(kDeliverNotifications)) 220 | { 221 | service->message(type, provider, argument); 222 | } 223 | } 224 | i->release(); 225 | } 226 | 227 | return( kIOReturnSuccess ); 228 | } 229 | -------------------------------------------------------------------------------- /VoodooPS2Controller/AppleACPIPS2Nub.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /*! @file AppleACPIPS2Nub.h 24 | @abstract AppleACPIPS2Nub class definition 25 | @discussion 26 | Implements the ACPI PS/2 nub for ApplePS2Controller.kext. 27 | Reverse-engineered from the Darwin 8 binary ACPI kext. 28 | Copyright 2007 David Elliott 29 | */ 30 | 31 | #ifndef __AppleACPIPS2Nub__ 32 | #define __AppleACPIPS2Nub__ 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #define EXPORT __attribute__((visibility("default"))) 39 | 40 | #define kDeliverNotifications "RM,deliverNotifications" 41 | 42 | class IOPlatformExpert; 43 | 44 | /*! @class AppleACPIPS2Nub 45 | @abstract Provides a nub that ApplePS2Controller can attach to 46 | @discussion 47 | The ApplePS2Controller driver is written to the nub provided by the 48 | AppleI386PlatformExpert class which exposes the controller as it is found 49 | on a legacy x86 machine. 50 | 51 | To make that kext work on an ACPI machine, a nub providing the same 52 | service must exist. Previous releases of the official ACPI PE included 53 | this class. Newer release do not. This implementation is intended 54 | to be fully ABI compatible with the one Apple used to provide. 55 | */ 56 | class EXPORT AppleACPIPS2Nub: public IOPlatformDevice 57 | { 58 | typedef IOPlatformDevice super; 59 | OSDeclareDefaultStructors(AppleACPIPS2Nub); 60 | 61 | private: 62 | /*! @field m_mouseProvider 63 | @abstract Our second provider which provides the mouse nub 64 | @discussion 65 | We attach to the keyboard nub but we need to be attached to both the 66 | keyboard and mouse nub in order to make ourselves a proper nub for 67 | the ApplePS2Controller.kext driver. 68 | */ 69 | IOService *m_mouseProvider; 70 | 71 | /*! @field m_interruptControllers 72 | @abstract Our array of interrupt controllers 73 | */ 74 | OSArray *m_interruptControllers; 75 | 76 | /*! @field m_interruptSpecifiers 77 | @abstract Our array of interrupt specifiers 78 | */ 79 | OSArray *m_interruptSpecifiers; 80 | 81 | enum LegacyInterrupts 82 | { 83 | LEGACY_KEYBOARD_IRQ = 1, 84 | LEGACY_MOUSE_IRQ = 12, 85 | }; 86 | 87 | public: 88 | virtual bool start(IOService *provider); 89 | 90 | /*! @method findMouseDevice 91 | @abstract Locates the mouse nub in the IORegistry 92 | */ 93 | virtual IOService *findMouseDevice(); 94 | 95 | /*! @method mergeInterruptProperties 96 | @abstract Merges the interrupt specifiers and controllers from our two providers 97 | @param pnpProvider The provider nub 98 | @discussion 99 | This is called once for each of our providers. The interrupt controller and interrupt 100 | specifier objects from the provider's arrays are appended to our arrays. 101 | */ 102 | virtual void mergeInterruptProperties(IOService *pnpProvider, long source); 103 | 104 | /*! @method registerInterrupt 105 | @abstract Overriden to translate the legacy interrupt numbers to ours 106 | @discussion 107 | The legacy interrupts are 1 for the keyboard and 12 (0xc) for the mouse. 108 | However, the base class code works off of the controller and specifier 109 | objects in our IOInterruptControllers and IOInterruptSpecifiers keys. 110 | Therefore, we must translate the keyboard interrupt (1) to the index 111 | into our array (0) and the mouse interrupt (12) to the index into 112 | our array (1). 113 | 114 | This has to be done for every *Interrupt* method 115 | */ 116 | virtual IOReturn registerInterrupt(int source, OSObject *target, 117 | IOInterruptAction handler, 118 | void *refCon = 0); 119 | virtual IOReturn unregisterInterrupt(int source); 120 | virtual IOReturn getInterruptType(int source, int *interruptType); 121 | virtual IOReturn enableInterrupt(int source); 122 | virtual IOReturn disableInterrupt(int source); 123 | 124 | /*! @method compareName 125 | @abstract Overridden to call the IOPlatformExpert compareNubName method 126 | @discussion 127 | I have no idea why this is done, but the Apple code did it, so this 128 | code does too. 129 | */ 130 | virtual bool compareName( OSString * name, OSString ** matched = 0 ) const; 131 | 132 | /*! @method getResources 133 | @abstract Overridden to call the IOPlatformExpert getNubResources method 134 | @discussion 135 | I have no idea why this is done, but the Apple code did it, so this 136 | code does too. 137 | */ 138 | virtual IOReturn getResources( void ); 139 | 140 | /*! @method message 141 | @abstract Overridden to receive ACPI notifications 142 | @discussion 143 | Allows the notifications to be forwarded to the keyboard device such that 144 | ACPI Notify can be used to push keystrokes. This is used to convert ACPI 145 | keys such that they appear to be PS2 keys. 146 | */ 147 | virtual IOReturn message( UInt32 type, IOService* provider, void* argument ); 148 | }; 149 | 150 | #endif -------------------------------------------------------------------------------- /VoodooPS2Controller/ApplePS2Device.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #include "ApplePS2Device.h" 24 | #include "VoodooPS2Controller.h" 25 | 26 | OSDefineMetaClassAndStructors(ApplePS2Device, IOService); 27 | 28 | // ============================================================================= 29 | // ApplePS2Device Class Implementation 30 | // 31 | 32 | bool ApplePS2Device::attach(IOService * provider) 33 | { 34 | if (!super::attach(provider)) 35 | return false; 36 | 37 | assert(_controller == 0); 38 | _controller = (ApplePS2Controller*)provider; 39 | _controller->retain(); 40 | 41 | return true; 42 | } 43 | 44 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 45 | 46 | void ApplePS2Device::detach( IOService * provider ) 47 | { 48 | assert(_controller == provider); 49 | _controller->release(); 50 | _controller = 0; 51 | 52 | super::detach(provider); 53 | } 54 | 55 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 56 | 57 | PS2Request * ApplePS2Device::allocateRequest(int max) 58 | { 59 | return _controller->allocateRequest(max); 60 | } 61 | 62 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 63 | 64 | void ApplePS2Device::freeRequest(PS2Request * request) 65 | { 66 | _controller->freeRequest(request); 67 | } 68 | 69 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 70 | 71 | bool ApplePS2Device::submitRequest(PS2Request * request) 72 | { 73 | return _controller->submitRequest(request); 74 | } 75 | 76 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 77 | 78 | void ApplePS2Device::submitRequestAndBlock(PS2Request * request) 79 | { 80 | _controller->submitRequestAndBlock(request); 81 | } 82 | 83 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 84 | 85 | UInt8 ApplePS2Device::setCommandByte(UInt8 setBits, UInt8 clearBits) 86 | { 87 | return _controller->setCommandByte(setBits, clearBits); 88 | } 89 | 90 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 91 | 92 | void ApplePS2Device::lock() 93 | { 94 | _controller->lock(); 95 | } 96 | 97 | void ApplePS2Device::unlock() 98 | { 99 | _controller->unlock(); 100 | } 101 | 102 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 103 | 104 | void ApplePS2Device::installInterruptAction(OSObject * target, 105 | PS2InterruptAction interruptAction, 106 | PS2PacketAction packetAction) 107 | { 108 | _controller->installInterruptAction(_deviceType, target, interruptAction, packetAction); 109 | } 110 | 111 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 112 | 113 | void ApplePS2Device::uninstallInterruptAction() 114 | { 115 | _controller->uninstallInterruptAction(_deviceType); 116 | } 117 | 118 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 119 | 120 | void ApplePS2Device::installPowerControlAction( 121 | OSObject * target, 122 | PS2PowerControlAction action) 123 | { 124 | _controller->installPowerControlAction(_deviceType, target, action); 125 | } 126 | 127 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 128 | 129 | void ApplePS2Device::uninstallPowerControlAction() 130 | { 131 | _controller->uninstallPowerControlAction(_deviceType); 132 | } 133 | 134 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 135 | 136 | void ApplePS2Device::installMessageAction(OSObject* target, PS2MessageAction action) 137 | { 138 | _controller->installMessageAction(_deviceType, target, action); 139 | } 140 | 141 | void ApplePS2Device::uninstallMessageAction() 142 | { 143 | _controller->uninstallMessageAction(_deviceType); 144 | } 145 | 146 | void ApplePS2Device::dispatchMouseMessage(int message, void *data) 147 | { 148 | _controller->dispatchMessage(kDT_Mouse, message, data); 149 | } 150 | 151 | void ApplePS2Device::dispatchKeyboardMessage(int message, void *data) 152 | { 153 | _controller->dispatchMessage(kDT_Keyboard, message, data); 154 | } 155 | 156 | -------------------------------------------------------------------------------- /VoodooPS2Controller/ApplePS2Device.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #ifndef _APPLEPS2DEVICE_H 24 | #define _APPLEPS2DEVICE_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #ifdef DEBUG_MSG 33 | #define DEBUG_LOG(args...) do { IOLog(args); } while (0) 34 | #else 35 | #define DEBUG_LOG(args...) do { } while (0) 36 | #endif 37 | 38 | #define countof(x) (sizeof((x))/sizeof((x)[0])) 39 | 40 | #define EXPORT __attribute__((visibility("default"))) 41 | 42 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 43 | // Definitions 44 | // 45 | // Data Port (0x60) Commands. These commands are all transmitted directly to 46 | // the physical keyboard and/or mouse, so expect an acknowledge for each byte 47 | // that you send through this port. 48 | // 49 | 50 | #define kDP_SetMouseScaling1To1 0xE6 // (mouse) 51 | #define kDP_SetMouseScaling2To1 0xE7 // (mouse) 52 | #define kDP_SetMouseResolution 0xE8 // (mouse) 53 | #define kDP_GetMouseInformation 0xE9 // (mouse) 54 | #define kDP_SetMouseStreamMode 0xEA // (mouse) 55 | #define kDP_MousePoll 0xEB // (mouse) caller sets number of bytes to receive 56 | #define kDP_MouseResetWrap 0xEC // (mouse) 57 | #define kDP_SetKeyboardLEDs 0xED // (keyboard) 58 | #define kDP_TestKeyboardEcho 0xEE // (keyboard) 59 | #define kDP_GetSetKeyboardASCs 0xF0 // (keyboard) 60 | #define kDP_MouseSetPoll 0xF0 // (mouse) 61 | #define kDP_GetId 0xF2 // (keyboard+mouse) 62 | #define kDP_SetKeyboardTypematic 0xF3 // (keyboard) 63 | #define kDP_SetMouseSampleRate 0xF3 // (mouse) 64 | #define kDP_Enable 0xF4 // (keyboard+mouse) 65 | #define kDP_SetDefaultsAndDisable 0xF5 // (keyboard+mouse) 66 | #define kDP_SetDefaults 0xF6 // (keyboard+mouse) 67 | #define kDP_SetAllTypematic 0xF7 // (keyboard) 68 | #define kDP_SetAllMakeRelease 0xF8 // (keyboard) 69 | #define kDP_SetAllMakeOnly 0xF9 // (keyboard) 70 | #define kDP_SetAllTypematicMakeRelease 0xFA // (keyboard) 71 | #define kDP_SetKeyMakeRelease 0xFB // (keyboard) 72 | #define kDP_SetKeyMakeOnly 0xFC // (keyboard) 73 | #define kDP_Reset 0xFF // (keyboard+mouse) 74 | 75 | // 76 | // Command Port (0x64) Commands. These commands all access registers local 77 | // to the motherboard, ie. nothing is transmitted, thus these commands and 78 | // any associated data passed thru the Data Port do not return acknowledges. 79 | // 80 | 81 | #define kCP_GetCommandByte 0x20 // (keyboard+mouse) 82 | #define kCP_ReadControllerRAMBase 0x21 // 83 | #define kCP_SetCommandByte 0x60 // (keyboard+mouse) 84 | #define kCP_WriteControllerRAMBase 0x61 // 85 | #define kCP_TestPassword 0xA4 // 86 | #define kCP_GetPassword 0xA5 // 87 | #define kCP_VerifyPassword 0xA6 // 88 | #define kCP_DisableMouseClock 0xA7 // (mouse) 89 | #define kCP_EnableMouseClock 0xA8 // (mouse) 90 | #define kCP_TestMousePort 0xA9 // 91 | #define kCP_TestController 0xAA // 92 | #define kCP_TestKeyboardPort 0xAB // 93 | #define kCP_GetControllerDiagnostic 0xAC // 94 | #define kCP_DisableKeyboardClock 0xAD // (keyboard) 95 | #define kCP_EnableKeyboardClock 0xAE // (keyboard) 96 | #define kCP_ReadInputPort 0xC0 // 97 | #define kCP_PollInputPortLow 0xC1 // 98 | #define kCP_PollInputPortHigh 0xC2 // 99 | #define kCP_ReadOutputPort 0xD0 // 100 | #define kCP_WriteOutputPort 0xD1 // 101 | #define kCP_WriteKeyboardOutputBuffer 0xD2 // (keyboard) 102 | #define kCP_WriteMouseOutputBuffer 0xD3 // (mouse) 103 | #define kCP_TransmitToMouse 0xD4 // (mouse) 104 | #define kCP_ReadTestInputs 0xE0 // 105 | #define kCP_PulseOutputBitBase 0xF0 // 106 | 107 | // 108 | // Bit definitions for the 8-bit "Command Byte" register, which is accessed 109 | // through the kCP_GetCommandByte/kCP_SetCommandByte. kCP_DisableMouseClock, 110 | // kCP_EnableMouseClock, kCP_DisableKeyboardClock, and kCP_EnableKeyboardClock 111 | // also affect this register. 112 | // 113 | 114 | #define kCB_EnableKeyboardIRQ 0x01 // Enable Keyboard IRQ 115 | #define kCB_EnableMouseIRQ 0x02 // Enable Mouse IRQ 116 | #define kCB_SystemFlag 0x04 // Set System Flag 117 | #define kCB_InhibitOverride 0x08 // Inhibit Override 118 | #define kCB_DisableKeyboardClock 0x10 // Disable Keyboard Clock 119 | #define kCB_DisableMouseClock 0x20 // Disable Mouse Clock 120 | #define kCB_TranslateMode 0x40 // Keyboard Translate Mode 121 | 122 | // 123 | // Bit definitions for the 8-bit "LED" register, which is accessed through 124 | // the Data Port (0x60) via kDP_SetKeyboardLEDs. Undefined bit positions must be zero. 125 | // 126 | 127 | #define kLED_ScrollLock 0x01 // Scroll Lock 128 | #define kLED_NumLock 0x02 // Num Lock 129 | #define kLED_CapsLock 0x04 // Caps Lock 130 | 131 | // 132 | // Scan Codes used for special purposes on the keyboard and/or mouse receive 133 | // port. These values would be received from your interrupt handler or from 134 | // a ReadDataPort command primitive. These values do not represent actual 135 | // keys, but indicate some sort of status. 136 | // 137 | 138 | #define kSC_Acknowledge 0xFA // ack for transmitted commands 139 | #define kSC_Extend 0xE0 // marker for "extended" sequence 140 | #define kSC_Pause 0xE1 // marker for pause key sequence 141 | #define kSC_Resend 0xFE // request to resend keybd cmd 142 | #define kSC_Reset 0xAA // the keyboard/mouse has reset 143 | #define kSC_UpBit 0x80 // OR'd in if key below is released 144 | #define kSC_ID 0x00 // PSMOUSE_RET_ID 145 | 146 | // 147 | // Scan Codes for some modifier keys. 148 | // 149 | 150 | #define kSC_Alt 0x38 // (extended = right key) 151 | #define kSC_Ctrl 0x1D // (extended = right key) 152 | #define kSC_ShiftLeft 0x2A 153 | #define kSC_ShiftRight 0x36 154 | #define kSC_WindowsLeft 0x5B // extended 155 | #define kSC_WindowsRight 0x5C // extended 156 | 157 | // 158 | // Scan Codes for some keys. 159 | // 160 | 161 | #define kSC_Delete 0x53 // (extended = gray key) 162 | #define kSC_NumLock 0x45 163 | 164 | // name of drivers/services as registered 165 | 166 | #define kApplePS2Controller "ApplePS2Controller" 167 | #define kApplePS2Keyboard "ApplePS2Keyboard" 168 | 169 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 170 | // RingBuffer 171 | // 172 | // A simple ring buffer class for devices to use in their real interrupt 173 | // routine for buffering packets. 174 | // 175 | // Standard FIFO ring buffer implemented as an array. 176 | // 177 | // Note: there is no error checking in this class. And no check for 178 | // overflow/underflow conditions. Make sure you have a large enough 179 | // buffer to handle your needs. And don't advance or try to fetch 180 | // data that doesn't exist (need to check result from count() first) 181 | // 182 | // This class is written for simplicity and efficiency, not to be 183 | // user friendly. 184 | // 185 | // The tail and head buffer can be accessed directly for effeciency, 186 | // but there are no provisions for dealing with "wrap-around," so it 187 | // is best that your buffer size is a mutliple of the packet size. 188 | // 189 | 190 | template 191 | class RingBuffer 192 | { 193 | private: 194 | T m_buffer[N]; 195 | volatile unsigned m_head; // m_head is volatile: commonly accessed at interrupt time 196 | unsigned m_tail; 197 | unsigned count(unsigned head, unsigned tail) 198 | { 199 | if (head >= tail) 200 | return head - tail; 201 | else 202 | return N - tail + head; 203 | } 204 | 205 | public: 206 | inline RingBuffer() { reset(); } 207 | void reset() 208 | { 209 | m_head = 0; 210 | m_tail = 0; 211 | } 212 | inline unsigned count() { return count(m_head, m_tail); } 213 | void push(T data) 214 | { 215 | // add new data to head, check for overflow. 216 | unsigned new_head = m_head + 1; 217 | if (new_head >= N) 218 | new_head = 0; 219 | if (new_head != m_tail) 220 | { 221 | m_buffer[m_head] = data; 222 | m_head = new_head; 223 | } 224 | } 225 | T fetch() 226 | { 227 | // grab new data from tail, no check for underflow. 228 | T result = m_buffer[m_tail++]; 229 | if (m_tail >= N) 230 | m_tail = 0; 231 | return result; 232 | } 233 | inline T* head() { return &m_buffer[m_head]; } 234 | inline T* tail() { return &m_buffer[m_tail]; } 235 | void advanceHead(unsigned move) 236 | { 237 | // advance head by specified amount, check for overflow 238 | unsigned new_head = m_head + move; 239 | if (new_head >= N) 240 | new_head -= N; 241 | if (count(new_head, m_tail) >= count()) 242 | m_head = new_head; 243 | } 244 | void advanceTail(unsigned move) 245 | { 246 | // advance tail by specified amount, no check for underflow. 247 | m_tail += move; 248 | if (m_tail >= N) 249 | m_tail -= N; 250 | } 251 | }; 252 | 253 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 254 | // PS/2 Command Primitives 255 | // 256 | // o kPS2C_ReadDataPort: 257 | // o Description: Reads the next available byte off the data port (60h). 258 | // o Out Field: Holds byte that was read. 259 | // 260 | // o kPS2C_ReadDataAndCompare: 261 | // o Description: Reads the next available byte off the data port (60h), 262 | // and compares it with the byte in the In Field. If the 263 | // comparison fails, the request is aborted (refer to the 264 | // commandsCount field in the request structure). 265 | // o In Field: Holds byte that comparison should be made to. 266 | // 267 | // o kPS2C_WriteDataPort: 268 | // o Description: Writes the byte in the In Field to the data port (60h). 269 | // o In Field: Holds byte that should be written. 270 | // 271 | // o kPS2C_WriteCommandPort: 272 | // o Description: Writes the byte in the In Field to the command port (64h). 273 | // o In Field: Holds byte that should be written. 274 | // 275 | 276 | enum PS2CommandEnum 277 | { 278 | kPS2C_ReadDataPort, 279 | kPS2C_ReadDataPortAndCompare, 280 | kPS2C_WriteDataPort, 281 | kPS2C_WriteCommandPort, 282 | kPS2C_SendMouseCommandAndCompareAck, 283 | kPS2C_ReadMouseDataPort, 284 | kPS2C_ReadMouseDataPortAndCompare, 285 | kPS2C_FlushDataPort, 286 | kPS2C_SleepMS, 287 | kPS2C_ModifyCommandByte, 288 | }; 289 | typedef enum PS2CommandEnum PS2CommandEnum; 290 | 291 | struct PS2Command 292 | { 293 | PS2CommandEnum command; 294 | union 295 | { 296 | UInt8 inOrOut; 297 | UInt32 inOrOut32; 298 | struct 299 | { 300 | UInt8 setBits; 301 | UInt8 clearBits; 302 | UInt8 oldBits; 303 | }; 304 | }; 305 | }; 306 | typedef struct PS2Command PS2Command; 307 | 308 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 309 | // PS/2 Request Structure 310 | // 311 | // o General Notes: 312 | // o allocateRequest allocates the request structure -- use it always. 313 | // o freeRequest deallocates the request structure -- use it always. 314 | // o It is the driver's responsibility to free the request structure: 315 | // o after a submitRequestAndBlock call returns, or 316 | // o in the completion routine for each submitRequest issued. 317 | // o It is not the driver's resposiblity to free the request structure: 318 | // o when no completion routine is specified in a request issued via 319 | // submitRequest, in which case the request is freed automatically 320 | // by the controller. This case is called "fire-and-forget". 321 | // o On completion, the requester can see how far the processing got by 322 | // looking at the commandsCount field. If it is equal to the original 323 | // number of commands, then the request was successful. If isn't, the 324 | // value represents the zero-based index of the command that failed. 325 | // 326 | // o General Notes For Inquisitive Minds: 327 | // o Requests are executed atomically with respect to all other requests, 328 | // that is, if a keyboard request is currently being processed, then a 329 | // request submitted by the mouse driver or one submitted by a separate 330 | // thread of control in the keyboard driver will get queued until the 331 | // controller is available again. 332 | // o Request processing can be preempted to service interrupts on other 333 | // PS/2 devices, should other-device data arrive unexpectedly on the 334 | // input stream while processing a request. 335 | // o The request processor knows when to read the mouse input stream 336 | // over the keyboard input stream for a given command sequence. It 337 | // does not depend on which driver it came from, rest assurred. If 338 | // the mouse driver so chose, it could send keyboard commands. 339 | // 340 | // o commands: 341 | // o Description: Holds list of commands that controller should execute. 342 | // o Comments: Refer to PS2Command structure. 343 | // 344 | // o commandsCount: 345 | // o Description: Holds the number of commands in the command list. 346 | // o Comments: Number of commands should never exceed kMaxCommands. 347 | // 348 | // o completionRoutineTarget, Action, and Param: 349 | // o Description: Object and method of the completion routine, which is 350 | // called when the request has finished. The Param field 351 | // may be filled with anything you want; it is passed to 352 | // completion routine when it is called. These fields 353 | // are optional. If left null, the request structure 354 | // will be deallocated automatically by the controller 355 | // on completion of the request. 356 | // o Prototype: void completionRoutine(void * target, void * param); 357 | // o Comments: Never issue submitRequestAndBlock or otherwise BLOCK on 358 | // any request sent down to your device from the completion 359 | // routine. Obey, or deadlock. 360 | // 361 | // Extensions for allocation by RehabMan 362 | // 363 | // Here are the possible ways to allocate/free the PS2Request structure. 364 | // All examples assume _device is pointer to ApplePS2MouseDevice or 365 | // ApplePS2KeyboardDevice. 366 | // 367 | // Legacy (allocation): 368 | // PS2Request* request = _device->allocateRequest(); 369 | // //... fill in request and submit 370 | // _device->freeRequest(request); 371 | // // Note: no need to free if using completionRoutine or on 372 | // // async submits. 373 | // 374 | // New way (allocation): 375 | // // specify number of commands 376 | // PS2Request* request = _device->allocateRequest(12); 377 | // 378 | // // allocate on stack 379 | // TPS2Request<12> request; 380 | // // Note: For obvious reasons, only valid with submitRequestAndBlock 381 | // 382 | // // allocate on stack using default size 383 | // TPS2Request<> request; 384 | // 385 | // // not allowed 386 | // PS2Request request; // no public constructor 387 | // 388 | // // allowed, but probably not a good idea: 389 | // TPS2Request request<0>; // equivalent to above 390 | // PS2Request* request = _device->allocateRequest(0); 391 | // 392 | // Deallocation: 393 | // _device->freeRequest(request); 394 | // 395 | // For stack-based allocation, and blocking submit do not 396 | // freeRequest or delete. 397 | // 398 | 399 | #define kMaxCommands 30 400 | 401 | typedef void (*PS2CompletionAction)(void * target, void * param); 402 | 403 | struct PS2Request 404 | { 405 | friend class ApplePS2Controller; 406 | 407 | protected: 408 | PS2Request(); 409 | static void* operator new(size_t); // "hide" it 410 | static inline void* operator new(size_t, int max) 411 | { return ::operator new(sizeof(PS2Request) + sizeof(PS2Command)*max); } 412 | static inline void operator delete(void*p) 413 | { ::operator delete(p); } 414 | 415 | public: 416 | UInt8 commandsCount; 417 | void * completionTarget; 418 | PS2CompletionAction completionAction; 419 | void * completionParam; 420 | queue_chain_t chain; 421 | PS2Command commands[0]; 422 | }; 423 | 424 | //template struct TPS2Request : public PS2Request 425 | // special completionTarget for TPS2Request allocated on stack 426 | #define kStackCompletionTarget ((void*)1) 427 | 428 | // PS2Requests with a completion target: completionAction frees the memory 429 | // PS2Requests allocated on the stack: completionTarget must be kStackCompletionTarget 430 | // PS2Requests with zero completionTarget: automatically freed upon completion 431 | 432 | // base class for templated PS2Request on the stack 433 | struct PS2RequestStack : public PS2Request 434 | { 435 | protected: 436 | PS2RequestStack() { completionTarget = kStackCompletionTarget; } 437 | }; 438 | 439 | template struct TPS2Request : public PS2RequestStack 440 | { 441 | public: 442 | PS2Command commands[max]; 443 | }; 444 | 445 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 446 | // ApplePS2KeyboardDevice and ApplePS2MouseDevice Class Descriptions 447 | // 448 | // 449 | // o General Notes: 450 | // o When the probe method is invoked on the client driver, the controller 451 | // guarantees that the keyboard clock is enabled and the keyboard itself 452 | // is disabled. This implies the client driver can send commands to the 453 | // keyboard without a problem, and the keyboard itself will not send any 454 | // asynchronous key data that may mess up the responses expected by the 455 | // commands sent to it. 456 | // 457 | // o installInterruptAction: 458 | // o Description: Ask the device to deliver asynchronous data to driver. 459 | // o In Fields: Target/action of completion routine. 460 | // 461 | // o installInterruptAction Interrupt Routine: 462 | // o Description: Delivers a newly read byte from the input data stream. 463 | // o Prototype: void interruptOccurred(void * target, UInt8 byte); 464 | // o In Fields: Byte that was read. 465 | // o Comments: Never issue submitRequestAndBlock or otherwise BLOCK on 466 | // any request sent down to your device from the interrupt 467 | // routine. Obey, or deadlock. 468 | // 469 | // o uninstallInterruptHandler: 470 | // o Description: Ask the device to stop delivering asynchronous data. 471 | // 472 | // o allocateRequest: 473 | // o Description: Allocate a request structure, blocks until successful. 474 | // o Result: Request structure pointer. 475 | // o Comments: Request structure is guaranteed to be zeroed. 476 | // 477 | // o freeRequest: 478 | // o Description: Deallocate a request structure. 479 | // o In Fields: Request structure pointer. 480 | // 481 | // o submitRequest: 482 | // o Description: Submit the request to the controller for processing. 483 | // o In Fields: Request structure pointer. 484 | // o Result: kern_return_t queueing status. 485 | // 486 | // o submitRequestAndBlock: 487 | // o Description: Submit the request to the controller for processing, then 488 | // block the calling thread until the request completes. 489 | // o In Fields: Request structure pointer. 490 | // 491 | 492 | enum PS2InterruptResult 493 | { 494 | kPS2IR_packetReady, 495 | kPS2IR_packetBuffering, 496 | }; 497 | 498 | typedef PS2InterruptResult (*PS2InterruptAction)(void * target, UInt8 data); 499 | 500 | typedef void (*PS2PacketAction)(void * target); 501 | 502 | // 503 | // Defines the prototype of an action registered by a PS/2 device driver to 504 | // intercept power changes on the PS/2 controller, and to manage the device 505 | // accordingly. 506 | // 507 | 508 | typedef void (*PS2PowerControlAction)(void * target, UInt32 whatToDo); 509 | 510 | // 511 | // Defines the prototype of an action registered by a PS/2 device driver 512 | // to communicate with either the mouse or keyboard partner. 513 | // 514 | // This is a extensible mechanism for keyboard driver to talk to 515 | // mouse/trackpad driver... or for mouse/trackpad driver to talk to 516 | // the keyboard driver. 517 | // 518 | 519 | typedef void (*PS2MessageAction)(void* target, int message, void* data); 520 | 521 | enum 522 | { 523 | // from keyboard to mouse/touchpad 524 | kPS2M_setDisableTouchpad, // set disable/enable touchpad (data is bool*) 525 | kPS2M_getDisableTouchpad, // get disable/enable touchpad (data is bool*) 526 | kPS2M_notifyKeyPressed, // notify of time key pressed (data is PS2KeyInfo*) 527 | 528 | // from mouse/touchpad to keyboard 529 | kPS2M_swipeDown, 530 | kPS2M_swipeUp, 531 | kPS2M_swipeLeft, 532 | kPS2M_swipeRight, 533 | kPS2M_swipe4Down, 534 | kPS2M_swipe4Up, 535 | kPS2M_swipe4Left, 536 | kPS2M_swipe4Right, 537 | }; 538 | 539 | typedef struct PS2KeyInfo 540 | { 541 | int64_t time; 542 | UInt16 adbKeyCode; 543 | bool goingDown; 544 | bool eatKey; 545 | } PS2KeyInfo; 546 | 547 | 548 | // 549 | // Enumeration of 'whatToDo' values passed to power control action. 550 | // 551 | 552 | enum 553 | { 554 | kPS2C_DisableDevice, 555 | kPS2C_EnableDevice 556 | }; 557 | 558 | // PS/2 device types. 559 | 560 | typedef enum 561 | { 562 | kDT_Keyboard, 563 | kDT_Mouse, 564 | #if WATCHDOG_TIMER 565 | kDT_Watchdog, 566 | #endif 567 | } PS2DeviceType; 568 | 569 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 570 | // ApplePS2Device Class Declaration 571 | // 572 | 573 | class ApplePS2Controller; 574 | 575 | class EXPORT ApplePS2Device : public IOService 576 | { 577 | typedef IOService super; 578 | OSDeclareDefaultStructors(ApplePS2Device); 579 | 580 | protected: 581 | ApplePS2Controller* _controller; 582 | PS2DeviceType _deviceType; 583 | 584 | public: 585 | virtual bool attach(IOService * provider); 586 | virtual void detach(IOService * provider); 587 | 588 | // Interrupt Handling Routines 589 | 590 | virtual void installInterruptAction(OSObject *, PS2InterruptAction, PS2PacketAction); 591 | virtual void uninstallInterruptAction(); 592 | 593 | // Request Submission Routines 594 | 595 | virtual PS2Request* allocateRequest(int max = kMaxCommands); 596 | virtual void freeRequest(PS2Request * request); 597 | virtual bool submitRequest(PS2Request * request); 598 | virtual void submitRequestAndBlock(PS2Request * request); 599 | virtual UInt8 setCommandByte(UInt8 setBits, UInt8 clearBits); 600 | 601 | // Power Control Handling Routines 602 | 603 | virtual void installPowerControlAction(OSObject *, PS2PowerControlAction); 604 | virtual void uninstallPowerControlAction(); 605 | 606 | // Messaging 607 | 608 | virtual void installMessageAction(OSObject*, PS2MessageAction); 609 | virtual void uninstallMessageAction(); 610 | virtual void dispatchMouseMessage(int message, void *data); 611 | virtual void dispatchKeyboardMessage(int message, void *data); 612 | 613 | // Exclusive access (command byte contention) 614 | 615 | virtual void lock(); 616 | virtual void unlock(); 617 | }; 618 | 619 | #if 0 // Note: Now using architecture/i386/pio.h (see above) 620 | typedef unsigned short i386_ioport_t; 621 | inline unsigned char inb(i386_ioport_t port) 622 | { 623 | unsigned char datum; 624 | asm volatile("inb %1, %0" : "=a" (datum) : "d" (port)); 625 | return(datum); 626 | } 627 | 628 | inline void outb(i386_ioport_t port, unsigned char datum) 629 | { 630 | asm volatile("outb %0, %1" : : "a" (datum), "d" (port)); 631 | } 632 | #endif 633 | 634 | #endif /* !_APPLEPS2DEVICE_H */ 635 | -------------------------------------------------------------------------------- /VoodooPS2Controller/ApplePS2KeyboardDevice.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #include "ApplePS2KeyboardDevice.h" 24 | #include "VoodooPS2Controller.h" 25 | 26 | // ============================================================================= 27 | // ApplePS2KeyboardDevice Class Implementation 28 | // 29 | 30 | OSDefineMetaClassAndStructors(ApplePS2KeyboardDevice, ApplePS2Device); 31 | 32 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 33 | 34 | bool ApplePS2KeyboardDevice::init() 35 | { 36 | bool result = super::init(); 37 | _deviceType = kDT_Keyboard; 38 | return result; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /VoodooPS2Controller/ApplePS2KeyboardDevice.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #ifndef _APPLEPS2KEYBOARDDEVICE_H 24 | #define _APPLEPS2KEYBOARDDEVICE_H 25 | 26 | #include "ApplePS2Device.h" 27 | 28 | class ApplePS2Controller; 29 | 30 | class EXPORT ApplePS2KeyboardDevice : public ApplePS2Device 31 | { 32 | typedef ApplePS2Device super; 33 | OSDeclareDefaultStructors(ApplePS2KeyboardDevice); 34 | 35 | public: 36 | virtual bool init(); 37 | }; 38 | 39 | #endif /* !_APPLEPS2KEYBOARDDEVICE_H */ 40 | -------------------------------------------------------------------------------- /VoodooPS2Controller/ApplePS2MouseDevice.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #include "ApplePS2MouseDevice.h" 24 | #include "VoodooPS2Controller.h" 25 | 26 | // ============================================================================= 27 | // ApplePS2MouseDevice Class Implementation 28 | // 29 | 30 | OSDefineMetaClassAndStructors(ApplePS2MouseDevice, ApplePS2Device); 31 | 32 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 33 | 34 | bool ApplePS2MouseDevice::init() 35 | { 36 | bool result = super::init(); 37 | _deviceType = kDT_Mouse; 38 | return result; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /VoodooPS2Controller/ApplePS2MouseDevice.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #ifndef _APPLEPS2MOUSEDEVICE_H 24 | #define _APPLEPS2MOUSEDEVICE_H 25 | 26 | #include "ApplePS2Device.h" 27 | 28 | class ApplePS2Controller; 29 | 30 | class EXPORT ApplePS2MouseDevice : public ApplePS2Device 31 | { 32 | typedef ApplePS2Device super; 33 | OSDeclareDefaultStructors(ApplePS2MouseDevice); 34 | 35 | public: 36 | virtual bool init(); 37 | }; 38 | 39 | #endif /* !_APPLEPS2MOUSEDEVICE_H */ 40 | -------------------------------------------------------------------------------- /VoodooPS2Controller/VoodooPS2Controller-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleExecutable 6 | VoodooPS2Controller 7 | CFBundleGetInfoString 8 | ${MODULE_VERSION}, Copyright Apple Computer, Inc. 2000-2003, David Elliot 2007, RehabMan 2012-2013 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Voodoo PS/2 Controller 15 | CFBundlePackageType 16 | KEXT 17 | CFBundleShortVersionString 18 | ${MODULE_VERSION} 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${MODULE_VERSION} 23 | IOKitPersonalities 24 | 25 | ACPI PS/2 Nub 26 | 27 | CFBundleIdentifier 28 | org.rehabman.voodoo.driver.PS2Controller 29 | IOClass 30 | AppleACPIPS2Nub 31 | IONameMatch 32 | 33 | PNP0303 34 | PNP030B 35 | 36 | IOProviderClass 37 | IOACPIPlatformDevice 38 | MouseNameMatch 39 | 40 | PNP0F03 41 | PNP0F0B 42 | PNP0F0E 43 | PNP0F13 44 | 45 | 46 | ApplePS2Controller 47 | 48 | CFBundleIdentifier 49 | org.rehabman.voodoo.driver.PS2Controller 50 | IOClass 51 | ApplePS2Controller 52 | IONameMatch 53 | ps2controller 54 | IOProviderClass 55 | IOPlatformDevice 56 | Platform Profile 57 | 58 | Default 59 | 60 | WakeDelay 61 | 10 62 | MouseWakeFirst 63 | 64 | 65 | HPQOEM 66 | 67 | 1411 68 | ProBook 69 | 1619 70 | ProBook 71 | 161C 72 | ProBook 73 | 164F 74 | ProBook 75 | 167C 76 | ProBook 77 | 167E 78 | ProBook 79 | 1680 80 | ProBook 81 | 179B 82 | ProBook 83 | 179C 84 | ProBook 85 | 17A9 86 | ProBook 87 | 17F0 88 | ProBook 89 | 17F3 90 | ProBook 91 | 17F6 92 | ProBook 93 | 1942 94 | ProBook 95 | 1949 96 | ProBook 97 | 198F 98 | ProBook 99 | ProBook 100 | 101 | WakeDelay 102 | 0 103 | 104 | 105 | Lenovo 106 | 107 | Haswell-Ideapad 108 | 109 | WakeDelay 110 | 0 111 | 112 | U430 113 | Haswell-Ideapad 114 | 115 | 116 | RM,Build 117 | ${CONFIGURATION}-${LOGNAME} 118 | RM,Version 119 | ${PRODUCT_NAME} ${MODULE_VERSION} 120 | 121 | 122 | OSBundleCompatibleVersion 123 | 2.8.15 124 | OSBundleLibraries 125 | 126 | com.apple.iokit.IOACPIFamily 127 | 1.0.0d1 128 | com.apple.kpi.bsd 129 | 8.0.0 130 | com.apple.kpi.iokit 131 | 8.0.0 132 | com.apple.kpi.libkern 133 | 8.0.0 134 | com.apple.kpi.mach 135 | 8.0.0 136 | com.apple.kpi.unsupported 137 | 8.0.0 138 | 139 | OSBundleRequired 140 | Console 141 | Source Code 142 | https://github.com/SergeySlice/OS-X-ALPS-DRIVER 143 | 144 | 145 | -------------------------------------------------------------------------------- /VoodooPS2Controller/VoodooPS2Controller-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'VoodooPS2Controller' target in the 'VoodooPS2Controller' project 3 | // 4 | 5 | -------------------------------------------------------------------------------- /VoodooPS2Controller/VoodooPS2Controller.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #ifndef _APPLEPS2CONTROLLER_H 24 | #define _APPLEPS2CONTROLLER_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include "ApplePS2Device.h" 30 | 31 | class ApplePS2KeyboardDevice; 32 | class ApplePS2MouseDevice; 33 | 34 | // 35 | // This section describes the problem with the PS/2 controller design and what 36 | // we are doing about it (OUT_OF_ORDER_DATA_CORRECTION_FEATURE). 37 | // 38 | // While the controller processes requests sent by the client drivers, at some 39 | // point in most requests, a read needs to be made from the data port to check 40 | // an acknowledge or receive some sort of data. We illustrate this issue with 41 | // an example -- a write LEDs request to the keyboard: 42 | // 43 | // 1. Write Write LED command. 44 | // 2. Read 0xFA Verify the acknowledge (0xFA). 45 | // 3. Write Write LED state. 46 | // 4. Read 0xFA Verify the acknowledge (0xFA). 47 | // 48 | // The problem is that the keyboard (when it is enabled) can send key events 49 | // to the controller at any time, including when the controller is expecting 50 | // to read an acknowledge next. What ends up happening is this sequence: 51 | // 52 | // a. Write Write LED command. 53 | // b. Read 0x21 Keyboard reports [F] key was depressed, not realizing that 54 | // we're still expecting a response to the command we JUST 55 | // sent the keyboard. We receive 0x21 as a response to our 56 | // command, and figure the command failed. 57 | // c. Get 0xFA Keyboard NOW decides to respond to the command with an 58 | // acknowledge. We're not waiting to read anything, so 59 | // this byte gets dispatched to the driver's interrupt 60 | // handler, which spews out an error message saying it 61 | // wasn't expecting an acknowledge. 62 | // 63 | // What can we do about this? In the above case, we can take note of the fact 64 | // that we are specifically looking for the 0xFA acknowledgement byte (through 65 | // the information passed in the kPS2C_ReadAndCompare primitive). If we don't 66 | // receive this byte next on the input data stream, we put the byte we did get 67 | // aside for a moment, and give the keyboard (or mouse) a second chance to 68 | // respond correctly. 69 | // 70 | // If we receive the 0xFA acknowledgement byte on the second read, that we 71 | // assume that situation described above just happened. We transparently 72 | // dispatch the first byte to the driver's interrupt handler, where it was 73 | // meant to go, and return the second correct byte to the read-and-compare 74 | // logic, where it was meant to go. Everyone wins. 75 | // 76 | // The only situation this feature cannot help is where a kPS2C_ReadDataPort 77 | // primitive is issued in place of a kPS2C_ReadDataPortAndCompare primitive. 78 | // This is necessary in some requests because the driver does not know what 79 | // it is going to receive. This can be illustrated in the mouse get info 80 | // command. 81 | // 82 | // 1. Write Prepare to write to mouse. 83 | // 2. Write Write information command. 84 | // 3. Read 0xFA Verify the acknowledge (0xFA). __-> mouse can report mouse 85 | // 4. Read Get first information byte. __-> packet bytes in between 86 | // 5. Read Get second information byte. __-> these reads 87 | // 6. Rrad Get third information byte. 88 | // 89 | // Controller cannot build any defenses against this. It is suggested that the 90 | // driver writer disable the mouse first, then send any dangerous commands, and 91 | // re-enable the mouse when the command completes. 92 | // 93 | // Note that the OUT_OF_ORDER_DATA_CORRECTION_FEATURE can be turned off at 94 | // compile time. Please see the readDataPort:expecting: method for more 95 | // information about the assumptions necessary for this feature. 96 | // 97 | 98 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 99 | // Definitions 100 | // 101 | 102 | // Enable debugger support (eg. mini-monitor). 103 | 104 | #define DEBUGGER_SUPPORT 0 105 | 106 | // Enable dynamic "second chance" re-ordering of input stream data if a 107 | // command response fails to match the expected byte. 108 | 109 | #define OUT_OF_ORDER_DATA_CORRECTION_FEATURE 1 110 | 111 | // Enable handling of interrupt data in workloop instead of at interrupt 112 | // time. This way is easier to debug. For production use, this should 113 | // be zero, such that PS2 data is buffered at real interrupt time, and handled 114 | // as packets later in the workloop. 115 | 116 | #define HANDLE_INTERRUPT_DATA_LATER 0 117 | #define WATCHDOG_TIMER 0 118 | 119 | // Interrupt definitions. 120 | 121 | #define kIRQ_Keyboard 1 122 | #define kIRQ_Mouse 12 123 | #define kIPL_Keyboard 6 124 | #define kIPL_Mouse 3 125 | 126 | // Port timings. 127 | 128 | #define kDataDelay 7 // usec to delay before data is valid 129 | 130 | // Ports used to control the PS/2 keyboard/mouse and read data from it. 131 | 132 | #define kDataPort 0x60 // keyboard data & cmds (read/write) 133 | #define kCommandPort 0x64 // keybd status (read), command (write) 134 | 135 | // Bit definitions for kCommandPort read values (status). 136 | 137 | #define kOutputReady 0x01 // output (from keybd) buffer full 138 | #define kInputBusy 0x02 // input (to keybd) buffer full 139 | #define kSystemFlag 0x04 // "System Flag" 140 | #define kCommandLastSent 0x08 // 1 = cmd, 0 = data last sent 141 | #define kKeyboardInhibited 0x10 // 0 if keyboard inhibited 142 | #define kMouseData 0x20 // mouse data available 143 | 144 | // Watchdog timer definitions 145 | 146 | #define kWatchdogTimerInterval 100 147 | 148 | #if DEBUGGER_SUPPORT 149 | // Definitions for our internal keyboard queue (holds keys processed by the 150 | // interrupt-time mini-monitor-key-sequence detection code). 151 | 152 | #define kKeyboardQueueSize 32 // number of KeyboardQueueElements 153 | 154 | typedef struct KeyboardQueueElement KeyboardQueueElement; 155 | struct KeyboardQueueElement 156 | { 157 | queue_chain_t chain; 158 | UInt8 data; 159 | }; 160 | #endif //DEBUGGER_SUPPORT 161 | 162 | // Info.plist definitions 163 | 164 | #define kDisableDevice "DisableDevice" 165 | #define kPlatformProfile "Platform Profile" 166 | 167 | #ifdef DEBUG 168 | #define kMergedConfiguration "Merged Configuration" 169 | #endif 170 | 171 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 172 | // ApplePS2Controller Class Declaration 173 | // 174 | 175 | class EXPORT ApplePS2Controller : public IOService 176 | { 177 | typedef IOService super; 178 | OSDeclareDefaultStructors(ApplePS2Controller); 179 | 180 | public: // interrupt-time variables and functions 181 | IOInterruptEventSource * _interruptSourceKeyboard; 182 | IOInterruptEventSource * _interruptSourceMouse; 183 | IOInterruptEventSource * _interruptSourceQueue; 184 | 185 | #if DEBUGGER_SUPPORT 186 | bool _debuggingEnabled; 187 | 188 | void lockController(int * state); 189 | void unlockController(int state); 190 | 191 | bool doEscape(UInt8 key); 192 | bool dequeueKeyboardData(UInt8 * key); 193 | void enqueueKeyboardData(UInt8 key); 194 | #endif //DEBUGGER_SUPPORT 195 | 196 | private: 197 | IOWorkLoop * _workLoop; 198 | queue_head_t _requestQueue; 199 | IOLock* _requestQueueLock; 200 | IOLock* _cmdbyteLock; 201 | 202 | OSObject * _interruptTargetKeyboard; 203 | OSObject * _interruptTargetMouse; 204 | PS2InterruptAction _interruptActionKeyboard; 205 | PS2InterruptAction _interruptActionMouse; 206 | PS2PacketAction _packetActionKeyboard; 207 | PS2PacketAction _packetActionMouse; 208 | bool _interruptInstalledKeyboard; 209 | bool _interruptInstalledMouse; 210 | 211 | OSObject * _powerControlTargetKeyboard; 212 | OSObject * _powerControlTargetMouse; 213 | PS2PowerControlAction _powerControlActionKeyboard; 214 | PS2PowerControlAction _powerControlActionMouse; 215 | bool _powerControlInstalledKeyboard; 216 | bool _powerControlInstalledMouse; 217 | 218 | int _ignoreInterrupts; 219 | int _ignoreOutOfOrder; 220 | 221 | OSObject* _messageTargetKeyboard; 222 | OSObject* _messageTargetMouse; 223 | PS2MessageAction _messageActionKeyboard; 224 | PS2MessageAction _messageActionMouse; 225 | bool _messageInstalledKeyboard; 226 | bool _messageInstalledMouse; 227 | 228 | ApplePS2MouseDevice * _mouseDevice; // mouse nub 229 | ApplePS2KeyboardDevice * _keyboardDevice; // keyboard nub 230 | 231 | #if DEBUGGER_SUPPORT 232 | IOSimpleLock * _controllerLock; // mach simple spin lock 233 | 234 | KeyboardQueueElement * _keyboardQueueAlloc; // queues' allocation space 235 | queue_head_t _keyboardQueue; // queue of available keys 236 | queue_head_t _keyboardQueueUnused; // queue of unused entries 237 | 238 | bool _extendedState; 239 | UInt16 _modifierState; 240 | #endif //DEBUGGER_SUPPORT 241 | 242 | thread_call_t _powerChangeThreadCall; 243 | UInt32 _currentPowerState; 244 | bool _hardwareOffline; 245 | bool _suppressTimeout; 246 | #ifdef NEWIRQ 247 | bool _newIRQLayout; 248 | #endif 249 | int _wakedelay; 250 | bool _mouseWakeFirst; 251 | IOCommandGate* _cmdGate; 252 | #if WATCHDOG_TIMER 253 | IOTimerEventSource* _watchdogTimer; 254 | #endif 255 | 256 | virtual PS2InterruptResult _dispatchDriverInterrupt(PS2DeviceType deviceType, UInt8 data); 257 | virtual void dispatchDriverInterrupt(PS2DeviceType deviceType, UInt8 data); 258 | #if HANDLE_INTERRUPT_DATA_LATER 259 | virtual void interruptOccurred(IOInterruptEventSource *, int); 260 | #else 261 | void packetReadyMouse(IOInterruptEventSource*, int); 262 | void packetReadyKeyboard(IOInterruptEventSource*, int); 263 | #endif 264 | void handleInterrupt(PS2DeviceType deviceType); 265 | #if WATCHDOG_TIMER 266 | void onWatchdogTimer(); 267 | #endif 268 | virtual void processRequest(PS2Request * request); 269 | virtual void processRequestQueue(IOInterruptEventSource *, int); 270 | 271 | virtual UInt8 readDataPort(PS2DeviceType deviceType); 272 | virtual void writeCommandPort(UInt8 byte); 273 | virtual void writeDataPort(UInt8 byte); 274 | void resetController(void); 275 | 276 | static void interruptHandlerMouse(OSObject*, void* refCon, IOService*, int); 277 | static void interruptHandlerKeyboard(OSObject*, void* refCon, IOService*, int); 278 | 279 | #if OUT_OF_ORDER_DATA_CORRECTION_FEATURE 280 | virtual UInt8 readDataPort(PS2DeviceType deviceType, UInt8 expectedByte); 281 | #endif 282 | 283 | static void setPowerStateCallout(thread_call_param_t param0, 284 | thread_call_param_t param1); 285 | 286 | static IOReturn setPowerStateAction(OSObject * target, 287 | void * arg0, void * arg1, 288 | void * arg2, void * arg3); 289 | 290 | virtual void setPowerStateGated(UInt32 newPowerState); 291 | 292 | virtual void dispatchDriverPowerControl(UInt32 whatToDo, PS2DeviceType deviceType); 293 | #if DEBUGGER_SUPPORT 294 | virtual void free(void); 295 | #endif 296 | IOReturn setPropertiesGated(OSObject* props); 297 | void submitRequestAndBlockGated(PS2Request* request); 298 | 299 | public: 300 | virtual bool init(OSDictionary * properties); 301 | virtual bool start(IOService * provider); 302 | virtual void stop(IOService * provider); 303 | 304 | virtual IOWorkLoop * getWorkLoop() const; 305 | 306 | virtual void installInterruptAction(PS2DeviceType deviceType, 307 | OSObject * target, 308 | PS2InterruptAction interruptAction, 309 | PS2PacketAction packetAction); 310 | virtual void uninstallInterruptAction(PS2DeviceType deviceType); 311 | 312 | virtual PS2Request* allocateRequest(int max = kMaxCommands); 313 | virtual void freeRequest(PS2Request * request); 314 | virtual bool submitRequest(PS2Request * request); 315 | virtual void submitRequestAndBlock(PS2Request * request); 316 | virtual UInt8 setCommandByte(UInt8 setBits, UInt8 clearBits); 317 | void setCommandByteGated(PS2Request* request); 318 | 319 | virtual IOReturn setPowerState(unsigned long powerStateOrdinal, 320 | IOService * policyMaker); 321 | 322 | virtual void installPowerControlAction(PS2DeviceType deviceType, 323 | OSObject * target, 324 | PS2PowerControlAction action); 325 | 326 | virtual void uninstallPowerControlAction(PS2DeviceType deviceType); 327 | 328 | virtual void installMessageAction(PS2DeviceType deviceType, 329 | OSObject * target, 330 | PS2MessageAction action); 331 | 332 | virtual void uninstallMessageAction(PS2DeviceType deviceType); 333 | virtual void dispatchMessage(PS2DeviceType deviceType, int message, void* data); 334 | 335 | virtual IOReturn setProperties(OSObject* props); 336 | virtual void lock(); 337 | virtual void unlock(); 338 | 339 | static OSDictionary* getConfigurationNode(OSDictionary* list, OSString* model = 0); 340 | static OSDictionary* makeConfigurationNode(OSDictionary* list, OSString* model = 0); 341 | }; 342 | 343 | #endif /* _APPLEPS2CONTROLLER_H */ 344 | -------------------------------------------------------------------------------- /VoodooPS2Controller/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | -------------------------------------------------------------------------------- /VoodooPS2Keyboard/VoodooPS2Keyboard-Breakless-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Source Code 6 | https://github.com/SergeySlice/OS-X-ALPS-DRIVER 7 | CFBundleGetInfoString 8 | ${MODULE_VERSION}, Copyright Apple Computer, Inc. 2000-2003, RehabMan 2012-2013 9 | CFBundleExecutable 10 | VoodooPS2Keyboard 11 | CFBundleIdentifier 12 | org.rehabman.voodoo.driver.PS2Keyboard 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Voodoo PS/2 Keyboard 17 | CFBundlePackageType 18 | KEXT 19 | CFBundleShortVersionString 20 | ${MODULE_VERSION} 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | ${MODULE_VERSION} 25 | IOKitPersonalities 26 | 27 | ApplePS2Keyboard 28 | 29 | CFBundleIdentifier 30 | org.rehabman.voodoo.driver.PS2Keyboard 31 | IOClass 32 | ApplePS2Keyboard 33 | IOProviderClass 34 | ApplePS2KeyboardDevice 35 | Platform Profile 36 | 37 | Default 38 | 39 | Make Application key into Apple Fn key 40 | 41 | Make Application key into right windows 42 | 43 | Make right modifier keys into Hangul and Hanja 44 | 45 | Swap capslock and left control 46 | 47 | Swap command and option 48 | 49 | Use ISO layout keyboard 50 | 51 | alt_handler_id 52 | 3 53 | SleepPressTime 54 | 3000 55 | Breakless PS2 56 | 57 | ;Items must be strings in the form of breaklessscan (in hex) 58 | e05f 59 | e012 60 | e017 61 | e06e 62 | e00a 63 | e009 64 | e020 65 | e02e 66 | e030 67 | e010 68 | e022 69 | e019 70 | 71 | Function Keys Standard 72 | 73 | ;Items must be strings in the form of scanfrom=scanto (in hex) 74 | ;The following 12 items map Fn+fkeys to Fn+fkeys 75 | e05f=e05f 76 | e012=e012 77 | e017=e017 78 | e06e=e06e 79 | e00a=e00a 80 | e009=e009 81 | e020=e020 82 | e02e=e02e 83 | e030=e030 84 | e010=e010 85 | e022=e022 86 | e019=e019 87 | ;The following 12 items map fkeys to fkeys 88 | 3b=3b 89 | 3c=3c 90 | 3d=3d 91 | 3e=3e 92 | 3f=3f 93 | 40=40 94 | 41=41 95 | 42=42 96 | 43=43 97 | 44=44 98 | 57=57 99 | 58=58 100 | 101 | Function Keys Special 102 | 103 | ;Items must be strings in the form of scanfrom=scanto (in hex) 104 | ;The following 12 items map Fn+fkeys to fkeys 105 | e05f=3b 106 | e012=3c 107 | e017=3d 108 | e06e=3e 109 | e00a=3f 110 | e009=40 111 | e020=41 112 | e02e=42 113 | e030=43 114 | e010=44 115 | e022=57 116 | e019=58 117 | ;The following 12 items map fkeys to Fn+fkeys 118 | 3b=e05f 119 | 3c=e012 120 | 3d=e017 121 | 3e=e06e 122 | 3f=e00a 123 | 40=e009 124 | 41=e020 125 | 42=e02e 126 | 43=e030 127 | 44=e010 128 | 57=e022 129 | 58=e019 130 | 131 | Custom PS2 Map 132 | 133 | ;Items must be strings in the form of scanfrom=scanto (in hex) 134 | 135 | Custom ADB Map 136 | 137 | ;Items must be strings in the form of scanfrom=adbto (in hex) 138 | 139 | ActionSwipeUp 140 | 3b d, 37 d, 7e d, 7e u, 37 u, 3b u 141 | ActionSwipeDown 142 | 3b d, 37 d, 7d d, 7d u, 37 u, 3b u 143 | ActionSwipeLeft 144 | 3b d, 37 d, 7b d, 7b u, 37 u, 3b u 145 | ActionSwipeRight 146 | 3b d, 37 d, 7c d, 7c u, 37 u, 3b u 147 | LogScanCodes 148 | 0 149 | 150 | 151 | 152 | 153 | OSBundleLibraries 154 | 155 | com.apple.iokit.IOHIDSystem 156 | 1.1 157 | com.apple.kpi.bsd 158 | 8.0.0 159 | com.apple.kpi.iokit 160 | 8.0.0 161 | com.apple.kpi.libkern 162 | 8.0.0 163 | com.apple.kpi.mach 164 | 8.0.0 165 | com.apple.kpi.unsupported 166 | 8.0.0 167 | org.rehabman.voodoo.driver.PS2Controller 168 | 2.8.15 169 | 170 | OSBundleRequired 171 | Console 172 | 173 | 174 | -------------------------------------------------------------------------------- /VoodooPS2Keyboard/VoodooPS2Keyboard-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleExecutable 6 | VoodooPS2Keyboard 7 | CFBundleGetInfoString 8 | ${MODULE_VERSION}, Copyright Apple Computer, Inc. 2000-2003, RehabMan 2012-2013 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Voodoo PS/2 Keyboard 15 | CFBundlePackageType 16 | KEXT 17 | CFBundleShortVersionString 18 | ${MODULE_VERSION} 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${MODULE_VERSION} 23 | IOKitPersonalities 24 | 25 | ApplePS2Keyboard 26 | 27 | CFBundleIdentifier 28 | org.rehabman.voodoo.driver.PS2Keyboard 29 | IOClass 30 | ApplePS2Keyboard 31 | IOProviderClass 32 | ApplePS2KeyboardDevice 33 | Platform Profile 34 | 35 | DELL 36 | 37 | Dell-Keys 38 | 39 | Breakless PS2 40 | 41 | e005 42 | e006 43 | 44 | Function Keys Special 45 | 46 | ;The following 12 items map Fn+fkeys to fkeys 47 | e020=3b 48 | e02e=3c 49 | e030=3d 50 | e022=3e 51 | ;Fn+f5 macro 52 | ;Fn+f6 macro 53 | ;Fn+f7 macro 54 | ;Fn+f8 macro 55 | ;Fn+f9 macro 56 | ;Fn+f10 no code 57 | e005=57 58 | e006=58 59 | ;The following 12 items map fkeys to Fn+fkeys 60 | 3b=e020 61 | 3c=e02e 62 | 3d=e030 63 | 3e=e022 64 | ;Fn+f5 macro 65 | ;Fn+f6 macro 66 | ;Fn+f7 macro 67 | ;Fn+f8 macro 68 | ;Fn+f9 macro 69 | ;Fn+f10 no code 70 | 57=e005 71 | 58=e006 72 | 73 | Function Keys Standard 74 | 75 | ;The following 12 items map Fn+fkeys to Fn+fkeys 76 | e020=e020 77 | e02e=e02e 78 | e030=e030 79 | e022=e022 80 | ;Fn+f5 macro 81 | ;Fn+f6 macro 82 | ;Fn+f7 macro 83 | ;Fn+f8 macro 84 | ;Fn+f9 macro 85 | ;Fn+f10 no code 86 | e005=e005 87 | e006=e006 88 | ;The following 12 items map fkeys to fkeys 89 | 3b=3b 90 | 3c=3c 91 | 3d=3d 92 | 3e=3e 93 | 3f=3f 94 | 40=40 95 | 41=41 96 | 42=42 97 | 43=43 98 | 44=44 99 | 57=57 100 | 58=58 101 | 102 | 103 | HSW-LPT 104 | Dell-Keys 105 | SNB-CPT 106 | 107 | ActionSwipeDown 108 | 63 d, 63 u 109 | ActionSwipeUp 110 | 61 d, 61 u 111 | Breakless PS2 112 | 113 | e01e;Touchpad Fn+f3 is breakless 114 | e06e;REVIEW: temporary for case that macro inversion does not work... 115 | 116 | Custom ADB Map 117 | 118 | e009=83;Dell Support to Launchpad 119 | e0f1=90;Call brightens up w RKA1 for special mode 120 | e0f2=91;Call brightens down w RKA2 for special mode 121 | e06e=70;Map vidmirror key for special mode default is adb90 122 | 123 | Custom PS2 Map 124 | 125 | e01e=e037;Map tp disable to Fn+f3 126 | e037=e01e;Prevent PrntScr from triggering tp disable 127 | 128 | Function Keys Special 129 | 130 | ;The following 12 items map Fn+fkeys to fkeys 131 | e06e=3b 132 | e008=3c 133 | e01e=3d 134 | e005=3e 135 | e006=3f 136 | e00c=40 137 | ;Fn+f7 no dedicated macro 138 | e010=42 139 | e022=43 140 | e019=44 141 | e02e=57 142 | e030=58 143 | ;The following 12 items map fkeys to Fn+fkeys 144 | 3b=e06e;Map vidmirror key to f1 145 | 3c=e0f0;Map radio toggle action from EC query to f2 146 | 3d=e037;Map touchpad toggle button to f3 147 | 3e=e0f2;Map acpi RKA2 to f4 brightness down 148 | 3f=e0f1;Map acpi RKA1 to f5 brightness up 149 | 40=e0f3;Map acpi RKA3 to f6 keyboard backlight 150 | ;Fn+f7 no macro 151 | 42=e010 152 | 43=e022 153 | 44=e019 154 | 57=e02e 155 | 58=e030 156 | 157 | Function Keys Standard 158 | 159 | ;The following 12 items map Fn+fkeys to Fn+fkeys 160 | e06e=e06e;Fn+f1 macro translated 161 | e008=e008;Fn+f2 regular scancode and EC query call q8c 162 | e01e=e037;Fn+f3 regular scancode and EC controls LED 163 | e005=e005;Fn+f4 no ps2scancode and EC query call q81 164 | e006=e006;Fn+f5 no ps2scancode and EC query call q80 165 | e00c=e00c;Fn+f6 no ps2scancode and EC query call q8a 166 | ;Fn+f7 no macro just regular f key 167 | e010=e010; Fn+f8 regular scancode 168 | e022=e022; Fn+f9 regular scancode 169 | e019=e019;Fn+f10 regular scancode 170 | e02e=e02e;Fn+f11 regular scancode 171 | e030=e030;Fn+f12 regular scancode 172 | ;Fn+f13 is mute dedicated button that always produces e020 regardless of Fn 173 | ;The following 12 items map fkeys to fkeys 174 | 3b=3b 175 | 3c=3c 176 | 3d=3d 177 | 3e=3e 178 | 3f=3f 179 | 40=40 180 | 41=41 181 | 42=42 182 | 43=43 183 | 44=44 184 | 57=57 185 | 58=58 186 | 187 | Macro Inversion 188 | 189 | ;This section maps ps2 codes (packet format) received quickly (macros) into fake ps2 codes (packet format) 190 | ;Fn+F1 191 | //8CbgAAAAACWwEZ 192 | //8C7gAAAAAC2wGZ 193 | //8C7gAAAAABmQLb 194 | 195 | MaximumMacroTime 196 | 35000000 197 | Note-Author 198 | TimeWalker aka TimeWalker75a 199 | Note-Comment 200 | Keyboard Profile for DELL SandyBridge SecureCore Tiano based laptops (Vostro 3450 & 3750, Inspiron N4110, XPS L502x & L702x & L511z) 201 | 202 | WN09 203 | 204 | Breakless PS2 205 | 206 | e01b 207 | e008 208 | e01e 209 | e005 210 | e06e 211 | e006 212 | 213 | Custom ADB Map 214 | 215 | e01b=70 216 | e06e=83 217 | e005=6b 218 | e006=71 219 | 220 | Custom PS2 Map 221 | 222 | 56=2b 223 | 29=56 224 | 2b=29 225 | e01e=e037 226 | e037=e01e 227 | 228 | 229 | 230 | Default 231 | 232 | ActionSwipeDown 233 | 3e d, 7d d, 7d u, 3e u 234 | ActionSwipeLeft 235 | 3b d, 7c d, 7c u, 3b u 236 | ActionSwipeRight 237 | 3b d, 7b d, 7b u, 3b u 238 | ActionSwipeUp 239 | 3b d, 7e d, 7e u, 3b u 240 | Breakless PS2 241 | 242 | ;Items must be strings in the form of breaklessscan (in hex) 243 | 244 | Custom ADB Map 245 | 246 | ;Items must be strings in the form of scanfrom=adbto (in hex) 247 | 248 | Custom PS2 Map 249 | 250 | ;Items must be strings in the form of scanfrom=scanto (in hex) 251 | e027=0;disable discrete fnkeys toggle 252 | e028=0;disable discrete trackpad toggle 253 | 254 | HIDF12EjectDelay 255 | 250 256 | LogScanCodes 257 | 0 258 | Make Application key into Apple Fn key 259 | 260 | Make Application key into right windows 261 | 262 | Make right modifier keys into Hangul and Hanja 263 | 264 | SleepPressTime 265 | 0 266 | Swap capslock and left control 267 | 268 | Swap command and option 269 | 270 | Use ISO layout keyboard 271 | 272 | alt_handler_id 273 | 3 274 | 275 | HPQOEM 276 | 277 | 1411 278 | ProBook-102;ProBook 4520s 279 | 1619 280 | ProBook-87;ProBook 6560b 281 | 161C 282 | ProBook-87;ProBook 8460p 283 | 164F 284 | ProBook-87;ProBook 5330m 285 | 167C 286 | ProBook-102;ProBook 4530s 287 | 167E 288 | ProBook-102;ProBook 4330s 289 | 1680 290 | ProBook-102;ProBook 4230s 291 | 179B 292 | ProBook-87;ProBook 6470b 293 | 179C 294 | ProBook-87;ProBook 6470b 295 | 17A9 296 | ProBook-87;ProBook 8570b 297 | 17F0 298 | ProBook-102;ProBook 4340s 299 | 17F3 300 | ProBook-102;ProBook 4440s 301 | 17F6 302 | ProBook-102;ProBook 4540s 303 | 1942 304 | ProBook-87;ProBook 450s G1 305 | 1949 306 | ProBook-87;ProBook 450s G1 307 | 1962 308 | Haswell-Envy;HP Envy 15-j063cl 309 | 1963 310 | Haswell-Envy;HP Envy 15-j063cl 311 | 1965 312 | Haswell-Envy;HP Envy 17t-j100 313 | 1966 314 | Haswell-Envy;HP Envy 17t-j000 315 | 198F 316 | ProBook-87;ProBook 450s G0 317 | Haswell-Envy 318 | 319 | BrightnessHack 320 | 321 | Custom ADB Map 322 | 323 | e019=42;next 324 | e010=4d;previous 325 | 326 | Custom PS2 Map 327 | 328 | e045=e037 329 | e0ab=0;bogus Fn+F2/F3 330 | 331 | 332 | ProBook-102 333 | 334 | Function Keys Special 335 | 336 | ;The following 12 items map Fn+fkeys to fkeys 337 | e05f=3b 338 | e012=3c 339 | e017=3d 340 | e06e=3e 341 | e00a=3f 342 | e009=40 343 | e020=41 344 | e02e=42 345 | e030=43 346 | e010=44 347 | e022=57 348 | e019=58 349 | ;The following 12 items map fkeys to Fn+fkeys 350 | 3b=e05f 351 | 3c=e012 352 | 3d=e017 353 | 3e=e06e 354 | 3f=e00a 355 | 40=e009 356 | 41=e020 357 | 42=e02e 358 | 43=e030 359 | 44=e010 360 | 57=e022 361 | 58=e019 362 | 363 | Function Keys Standard 364 | 365 | ;The following 12 items map Fn+fkeys to Fn+fkeys 366 | e05f=e05f 367 | e012=e012 368 | e017=e017 369 | e06e=e06e 370 | e00a=e00a 371 | e009=e009 372 | e020=e020 373 | e02e=e02e 374 | e030=e030 375 | e010=e010 376 | e022=e022 377 | e019=e019 378 | ;The following 12 items map fkeys to fkeys 379 | 3b=3b 380 | 3c=3c 381 | 3d=3d 382 | 3e=3e 383 | 3f=3f 384 | 40=40 385 | 41=41 386 | 42=42 387 | 43=43 388 | 44=44 389 | 57=57 390 | 58=58 391 | 392 | SleepPressTime 393 | 3000 394 | 395 | ProBook-87 396 | 397 | Custom ADB Map 398 | 399 | 46=4d;scroll => Previous-track 400 | e045=34;pause => Play-Pause 401 | e052=42;insert => Next-track 402 | e046=92;break => Eject 403 | 404 | Function Keys Special 405 | 406 | ;The following 8 items map Fn+fkeys to fkeys 407 | e05f=3d 408 | e06e=3e 409 | e02e=40 410 | e030=41 411 | e009=42 412 | e012=43 413 | e017=44 414 | e033=57 415 | ;The following 8 items map fkeys to Fn+fkeys 416 | 3d=e05f 417 | 3e=e06e 418 | 40=e02e 419 | 41=e030 420 | 42=e037 421 | 43=e012 422 | 44=e017 423 | 424 | Function Keys Standard 425 | 426 | ;The following 8 items map Fn+fkeys to Fn+fkeys 427 | e05f=e05f 428 | e06e=e06e 429 | e02e=e02e 430 | e030=e030 431 | e009=e009 432 | e012=e012 433 | e017=e017 434 | e033=e033 435 | ;The following 8 items map fkeys to fkeys 436 | 3d=3d 437 | 3e=3e 438 | 40=40 439 | 41=41 440 | 42=42 441 | 43=43 442 | 44=44 443 | 444 | SleepPressTime 445 | 3000 446 | 447 | 448 | Intel 449 | 450 | CALPELLA 451 | SamsungKeys 452 | SamsungKeys 453 | 454 | Breakless PS2 455 | 456 | e003 457 | e002 458 | e004 459 | e020 460 | ;e031 461 | e033 462 | e006 463 | e077 464 | e079 465 | e008 466 | e009 467 | 468 | Custom ADB Map 469 | 470 | e002=70 471 | e006=80 472 | e008=90 473 | e009=91 474 | 475 | Function Keys Special 476 | 477 | ;The following 12 items map Fn+fkeys to fkeys 478 | ;fn+f1 no code 479 | e003=3c 480 | ;fn+f3 weird code 481 | e002=3e 482 | e004=3f 483 | e020=40 484 | e031=41 485 | e033=42 486 | e006=43 487 | ;fn+f10 weird code 488 | ;fn+f11 no code 489 | ;fn+f12 scrolllock 490 | ;The following 12 items map fkeys to Fn+fkeys 491 | ;fn+f1 no code 492 | 3c=e003 493 | ;fn+f3 weird code 494 | 3e=e002 495 | 3f=e004 496 | 40=e020 497 | 41=e031 498 | 42=e033 499 | 43=e006 500 | ;fn+f10 weird code 501 | ;fn+f11 no code 502 | ;fn+f12 scrolllock 503 | 504 | Function Keys Standard 505 | 506 | ;The following 12 items map Fn+fkeys to Fn+fkeys 507 | ;fn+f1 no code 508 | e003=e003 509 | ;fn+f3 weird code 510 | e002=e002 511 | e004=e004 512 | e020=e020 513 | e031=e031 514 | e033=e033 515 | e006=e006 516 | ;fn+f10 weird code 517 | ;fn+f11 no code 518 | ;fn+f12 scrolllock 519 | ;The following 12 items map fkeys to fkeys 520 | 3b=3b 521 | 3c=3c 522 | 3d=3d 523 | 3e=3e 524 | 3f=3f 525 | 40=40 526 | 41=41 527 | 42=42 528 | 43=43 529 | 44=44 530 | 57=57 531 | 58=58 532 | 533 | 534 | 535 | LENOVO 536 | 537 | Haswell-Ideapad 538 | 539 | Breakless PS2 540 | 541 | e064 542 | e065 543 | e068 544 | e06a 545 | e027 546 | 547 | Custom ADB Map 548 | 549 | e063=3f;Apple Fn 550 | e064=6b;F14 551 | e065=71;F15 552 | e068=4f;F18 553 | e0f2=65;special F9 554 | e0fb=91;brightness down 555 | e0fc=90;brightness up 556 | e06a=70;video mirror 557 | 558 | Custom PS2 Map 559 | 560 | e037=64;PrtSc=F13 561 | 562 | Function Keys Special 563 | 564 | ;The following 12 items map Fn+fkeys to Fn+fkeys 565 | e020=e020 566 | e02e=e02e 567 | e030=e030 568 | e064=e064 569 | e065=e065 570 | e066=e028 571 | e067=e067 572 | e068=e068 573 | e069=e0f0 574 | e06a=e06a 575 | e06b=e0fb 576 | e06c=e0fc 577 | ;The following 12 items map fkeys to fkeys 578 | 3b=3b 579 | 3c=3c 580 | 3d=3d 581 | 3e=3e 582 | 3f=3f 583 | 40=40 584 | 41=41 585 | 42=42 586 | 43=43 587 | 44=44 588 | 57=57 589 | 58=58 590 | 591 | Function Keys Standard 592 | 593 | ;The following 12 items map Fn+fkeys to fkeys 594 | e020=3b 595 | e02e=3c 596 | e030=3d 597 | e064=3e 598 | e065=3f 599 | e066=40 600 | e067=41 601 | e068=42 602 | e069=e0f2 603 | e06a=44 604 | e06b=57 605 | e06c=58 606 | ;The following 12 items map fkeys to Fn+fkeys 607 | 3b=e020 608 | 3c=e02e 609 | 3d=e030 610 | 3e=e064 611 | 3f=e065 612 | 40=e028 613 | 41=e067 614 | 42=e068 615 | 43=e0f1 616 | 44=e06a 617 | 57=e0fb 618 | 58=e0fc 619 | 620 | Macro Inversion 621 | 622 | ;This section maps ps2 codes (packet format) received quickly (macros) into fake ps2 codes (packet format) 623 | ;Fn+F4 624 | //8CZAAAAAABOAE+ 625 | //8C5AAAAAABvgG4 626 | ;F5 (without Fn) 627 | //8CZQEAAAABPw== 628 | //8C5QEAAAABvw== 629 | ;Fn+Ctrl+F6 630 | //8CJwAD//8CZg== 631 | //8CpwAD//8C5g== 632 | ;Ctrl+F6 633 | //8CJwAD//8CQA== 634 | //8CpwAD//8CwA== 635 | ;Fn+F8 636 | //8CaAAAAAACHQE4AQ8= 637 | //8C6AAAAAABjwG4Ap0= 638 | ;Fn+F10 639 | //8CagAAAAACWwEZ 640 | //8C6gAAAAABmQLb 641 | 642 | Macro Translation 643 | 644 | ;This section maps ps2 codes (packet format) + modifiers to one more ps2 codes (packet format) 645 | 646 | MaximumMacroTime 647 | 25000000 648 | 649 | U430 650 | Haswell-Ideapad 651 | 652 | SECCSD 653 | 654 | LH43STAR 655 | SamsungKeys 656 | SamsungKeys 657 | 658 | Breakless PS2 659 | 660 | e020 661 | e02e 662 | e030 663 | 664 | 665 | 666 | 667 | 668 | 669 | OSBundleLibraries 670 | 671 | com.apple.iokit.IOHIDSystem 672 | 1.1 673 | com.apple.kpi.bsd 674 | 8.0.0 675 | com.apple.kpi.iokit 676 | 8.0.0 677 | com.apple.kpi.libkern 678 | 8.0.0 679 | com.apple.kpi.mach 680 | 8.0.0 681 | com.apple.kpi.unsupported 682 | 8.0.0 683 | org.rehabman.voodoo.driver.PS2Controller 684 | 2.8.15 685 | 686 | OSBundleRequired 687 | Console 688 | Source Code 689 | https://github.com/SergeySlice/OS-X-ALPS-DRIVER 690 | 691 | 692 | -------------------------------------------------------------------------------- /VoodooPS2Keyboard/VoodooPS2Keyboard-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'VoodooPS2Keyboard' target in the 'VoodooPS2Keyboard' project 3 | // 4 | 5 | -------------------------------------------------------------------------------- /VoodooPS2Keyboard/VoodooPS2Keyboard-RemapFN-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Source Code 6 | https://github.com/RehabMan/OS-X-Voodoo-PS2-Controller 7 | CFBundleGetInfoString 8 | ${MODULE_VERSION}, Copyright Apple Computer, Inc. 2000-2003, RehabMan 2012-2013 9 | CFBundleExecutable 10 | VoodooPS2Keyboard 11 | CFBundleIdentifier 12 | org.rehabman.voodoo.driver.PS2Keyboard 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Voodoo PS/2 Keyboard 17 | CFBundlePackageType 18 | KEXT 19 | CFBundleShortVersionString 20 | ${MODULE_VERSION} 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | ${MODULE_VERSION} 25 | IOKitPersonalities 26 | 27 | ApplePS2Keyboard 28 | 29 | CFBundleIdentifier 30 | org.rehabman.voodoo.driver.PS2Keyboard 31 | IOClass 32 | ApplePS2Keyboard 33 | IOProviderClass 34 | ApplePS2KeyboardDevice 35 | Platform Profile 36 | 37 | Default 38 | 39 | Make Application key into Apple Fn key 40 | 41 | Make Application key into right windows 42 | 43 | Make right modifier keys into Hangul and Hanja 44 | 45 | Swap capslock and left control 46 | 47 | Swap command and option 48 | 49 | Use ISO layout keyboard 50 | 51 | alt_handler_id 52 | 3 53 | SleepPressTime 54 | 3000 55 | Breakless PS2 56 | 57 | ;Items must be strings in the form of breaklessscan (in hex) 58 | 59 | Function Keys Standard 60 | 61 | ;Items must be strings in the form of scanfrom=scanto (in hex) 62 | ;The following 12 items map Fn+fkeys to Fn+fkeys 63 | e05f=e05f 64 | e012=e012 65 | e017=e017 66 | e06e=e06e 67 | e00a=e00a 68 | e009=e009 69 | e020=e020 70 | e02e=e02e 71 | e030=e030 72 | e010=e010 73 | e022=e022 74 | e019=e019 75 | ;The following 12 items map fkeys to fkeys 76 | 3b=3b 77 | 3c=3c 78 | 3d=3d 79 | 3e=3e 80 | 3f=3f 81 | 40=40 82 | 41=41 83 | 42=42 84 | 43=43 85 | 44=44 86 | 57=57 87 | 58=58 88 | 89 | Function Keys Special 90 | 91 | ;Items must be strings in the form of scanfrom=scanto (in hex) 92 | ;The following 12 items map Fn+fkeys to fkeys 93 | e05f=3b 94 | e012=3c 95 | e017=3d 96 | e06e=3e 97 | e00a=3f 98 | e009=40 99 | e020=41 100 | e02e=42 101 | e030=43 102 | e010=44 103 | e022=57 104 | e019=58 105 | ;The following 12 items map fkeys to Fn+fkeys 106 | 3b=e05f 107 | 3c=e012 108 | 3d=e017 109 | 3e=e06e 110 | 3f=e00a 111 | 40=e009 112 | 41=e020 113 | 42=e02e 114 | 43=e030 115 | 44=e010 116 | 57=e022 117 | 58=e019 118 | 119 | Custom PS2 Map 120 | 121 | ;Items must be strings in the form of scanfrom=scanto (in hex) 122 | 123 | Custom ADB Map 124 | 125 | ;Items must be strings in the form of scanfrom=adbto (in hex) 126 | 127 | ActionSwipeUp 128 | 3e d, 7e d, 7e u, 3e u< 129 | ActionSwipeDown 130 | 3b d, 37 d, 7d d, 7d u, 37 u, 3b u 131 | ActionSwipeLeft 132 | 3e d, 7c d, 7c u, 3e u 133 | ActionSwipeRight 134 | 3e d, 7b d, 7b u, 3e u 135 | LogScanCodes 136 | 0 137 | 138 | 139 | 140 | 141 | OSBundleLibraries 142 | 143 | com.apple.iokit.IOHIDSystem 144 | 1.1 145 | com.apple.kpi.bsd 146 | 8.0.0 147 | com.apple.kpi.iokit 148 | 8.0.0 149 | com.apple.kpi.libkern 150 | 8.0.0 151 | com.apple.kpi.mach 152 | 8.0.0 153 | com.apple.kpi.unsupported 154 | 8.0.0 155 | org.rehabman.voodoo.driver.PS2Controller 156 | 2.8.15 157 | 158 | OSBundleRequired 159 | Console 160 | 161 | 162 | -------------------------------------------------------------------------------- /VoodooPS2Keyboard/VoodooPS2Keyboard.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SergeySlice/VoodooPS2-for-ALPS/241dca08ae09a172ded3c345e455f68c979d7e67/VoodooPS2Keyboard/VoodooPS2Keyboard.cpp -------------------------------------------------------------------------------- /VoodooPS2Keyboard/VoodooPS2Keyboard.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #ifndef _APPLEPS2KEYBOARD_H 24 | #define _APPLEPS2KEYBOARD_H 25 | 26 | #include 27 | #include "ApplePS2KeyboardDevice.h" 28 | #include 29 | #include 30 | #include 31 | 32 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 33 | // Definitions used to keep track of key state. Key up/down state is tracked 34 | // in a bit list. Bits are set for key-down, and cleared for key-up. The bit 35 | // vector and macros for it's manipulation are defined here. 36 | // 37 | 38 | #define KBV_NUM_KEYCODES 512 // related with ADB_CONVERTER_LEN 39 | #define KBV_BITS_PER_UNIT 32 // for UInt32 40 | #define KBV_BITS_MASK 31 41 | #define KBV_BITS_SHIFT 5 // 1<<5 == 32, for cheap divide 42 | #define KBV_NUNITS ((KBV_NUM_KEYCODES + \ 43 | (KBV_BITS_PER_UNIT-1))/KBV_BITS_PER_UNIT) 44 | 45 | #define KBV_KEYDOWN(n) \ 46 | (_keyBitVector)[((n)>>KBV_BITS_SHIFT)] |= (1 << ((n) & KBV_BITS_MASK)) 47 | 48 | #define KBV_KEYUP(n) \ 49 | (_keyBitVector)[((n)>>KBV_BITS_SHIFT)] &= ~(1 << ((n) & KBV_BITS_MASK)) 50 | 51 | #define KBV_IS_KEYDOWN(n) \ 52 | (((_keyBitVector)[((n)>>KBV_BITS_SHIFT)] & (1 << ((n) & KBV_BITS_MASK))) != 0) 53 | 54 | #define KBV_NUM_SCANCODES 256 55 | 56 | // Special bits for _PS2ToPS2Map 57 | 58 | #define kBreaklessKey 0x01 // keys with this flag don't generate break codes 59 | 60 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 61 | // ApplePS2Keyboard Class Declaration 62 | // 63 | 64 | #define kPacketLength (2+6+8) // 2 bytes for key data, 6-bytes not used, 8 bytes for timestamp 65 | #define kPacketKeyOffset 0 66 | #define kPacketTimeOffset 8 67 | #define kPacketKeyDataLength 2 68 | 69 | class EXPORT ApplePS2Keyboard : public IOHIKeyboard 70 | { 71 | typedef IOHIKeyboard super; 72 | OSDeclareDefaultStructors(ApplePS2Keyboard); 73 | 74 | private: 75 | ApplePS2KeyboardDevice * _device; 76 | UInt32 _keyBitVector[KBV_NUNITS]; 77 | UInt8 _extendCount; 78 | RingBuffer _ringBuffer; 79 | UInt8 _lastdata; 80 | bool _interruptHandlerInstalled; 81 | bool _powerControlHandlerInstalled; 82 | bool _messageHandlerInstalled; 83 | UInt8 _ledState; 84 | IOCommandGate* _cmdGate; 85 | 86 | // for keyboard remapping 87 | UInt16 _PS2modifierState; 88 | UInt16 _PS2ToPS2Map[KBV_NUM_SCANCODES*2]; 89 | UInt16 _PS2flags[KBV_NUM_SCANCODES*2]; 90 | UInt8 _PS2ToADBMap[ADB_CONVERTER_LEN]; 91 | UInt8 _PS2ToADBMapMapped[ADB_CONVERTER_LEN]; 92 | UInt32 _fkeymode; 93 | bool _fkeymodesupported; 94 | OSArray* _keysStandard; 95 | OSArray* _keysSpecial; 96 | bool _swapcommandoption; 97 | int _logscancodes; 98 | UInt32 _f12ejectdelay; 99 | enum { kTimerSleep, kTimerEject } _timerFunc; 100 | 101 | // dealing with sleep key delay 102 | IOTimerEventSource* _sleepEjectTimer; 103 | UInt32 _maxsleeppresstime; 104 | 105 | // configuration items for swipe actions 106 | UInt16 _actionSwipeUp[16]; 107 | UInt16 _actionSwipeDown[16]; 108 | UInt16 _actionSwipeLeft[16]; 109 | UInt16 _actionSwipeRight[16]; 110 | UInt16 _actionSwipe4Up[16]; 111 | UInt16 _actionSwipe4Down[16]; 112 | UInt16 _actionSwipe4Left[16]; 113 | UInt16 _actionSwipe4Right[16]; 114 | 115 | // ACPI support for screen brightness 116 | IOACPIPlatformDevice * _provider; 117 | int * _brightnessLevels; 118 | int _brightnessCount; 119 | 120 | // ACPI support for keyboard backlight 121 | int * _backlightLevels; 122 | int _backlightCount; 123 | 124 | // special hack for Envy brightness access, while retaining F2/F3 functionality 125 | bool _brightnessHack; 126 | 127 | // macro processing 128 | OSData** _macroTranslation; 129 | OSData** _macroInversion; 130 | UInt8* _macroBuffer; 131 | int _macroMax; 132 | int _macroCurrent; 133 | uint64_t _macroMaxTime; 134 | IOTimerEventSource* _macroTimer; 135 | 136 | virtual bool dispatchKeyboardEventWithPacket(const UInt8* packet); 137 | virtual void setLEDs(UInt8 ledState); 138 | virtual void setKeyboardEnable(bool enable); 139 | virtual void initKeyboard(); 140 | virtual void setDevicePowerState(UInt32 whatToDo); 141 | void sendKeySequence(UInt16* pKeys); 142 | void modifyKeyboardBacklight(int adbKeyCode, bool goingDown); 143 | void modifyScreenBrightness(int adbKeyCode, bool goingDown); 144 | inline bool checkModifierState(UInt16 mask) 145 | { return mask == (_PS2modifierState & mask); } 146 | 147 | void loadCustomPS2Map(OSArray* pArray); 148 | void loadBreaklessPS2(OSDictionary* dict, const char* name); 149 | void loadCustomADBMap(OSDictionary* dict, const char* name); 150 | void setParamPropertiesGated(OSDictionary* dict); 151 | void onSleepEjectTimer(void); 152 | 153 | static OSData** loadMacroData(OSDictionary* dict, const char* name); 154 | static void freeMacroData(OSData** data); 155 | void onMacroTimer(void); 156 | bool invertMacros(const UInt8* packet); 157 | void dispatchInvertBuffer(); 158 | static bool compareMacro(const UInt8* packet, const UInt8* data, int count); 159 | 160 | protected: 161 | virtual const unsigned char * defaultKeymapOfLength(UInt32 * length); 162 | virtual void setAlphaLockFeedback(bool locked); 163 | virtual void setNumLockFeedback(bool locked); 164 | virtual UInt32 maxKeyCodes(); 165 | inline void dispatchKeyboardEventX(unsigned int keyCode, bool goingDown, uint64_t time) 166 | { dispatchKeyboardEvent(keyCode, goingDown, *(AbsoluteTime*)&time); } 167 | inline void setTimerTimeout(IOTimerEventSource* timer, uint64_t time) 168 | { timer->setTimeout(*(AbsoluteTime*)&time); } 169 | inline void cancelTimer(IOTimerEventSource* timer) 170 | { timer->cancelTimeout(); } 171 | 172 | public: 173 | virtual bool init(OSDictionary * dict); 174 | virtual void free(); 175 | virtual ApplePS2Keyboard * probe(IOService * provider, SInt32 * score); 176 | 177 | virtual bool start(IOService * provider); 178 | virtual void stop(IOService * provider); 179 | 180 | virtual PS2InterruptResult interruptOccurred(UInt8 scanCode); 181 | virtual void packetReady(); 182 | 183 | virtual void receiveMessage(int message, void* data); 184 | 185 | virtual UInt32 deviceType(); 186 | virtual UInt32 interfaceID(); 187 | 188 | virtual IOReturn setParamProperties(OSDictionary* dict); 189 | virtual IOReturn setProperties (OSObject *props); 190 | 191 | virtual IOReturn message(UInt32 type, IOService* provider, void* argument); 192 | }; 193 | 194 | #endif /* _APPLEPS2KEYBOARD_H */ 195 | -------------------------------------------------------------------------------- /VoodooPS2Keyboard/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | -------------------------------------------------------------------------------- /VoodooPS2Trackpad/Decay.h: -------------------------------------------------------------------------------- 1 | // 2 | // Decay.h 3 | // VoodooPS2Controller 4 | // 5 | // Created by Brandon Pedersen on 5/4/13. 6 | // Copyright (c) 2013 rehabman. All rights reserved. 7 | // 8 | 9 | #ifndef VoodooPS2Controller_Decay_h 10 | #define VoodooPS2Controller_Decay_h 11 | 12 | template 13 | class SimpleAverage 14 | { 15 | private: 16 | T m_buffer[N]; 17 | int m_count; 18 | int m_sum; 19 | int m_index; 20 | 21 | public: 22 | inline SimpleAverage() { reset(); } 23 | T filter(T data) 24 | { 25 | // add new entry to sum 26 | m_sum += data; 27 | // if full buffer, then we are overwriting, so subtract old from sum 28 | if (m_count == N) 29 | m_sum -= m_buffer[m_index]; 30 | // new entry into buffer 31 | m_buffer[m_index] = data; 32 | // move index to next position with wrap around 33 | if (++m_index >= N) 34 | m_index = 0; 35 | // keep count moving until buffer is full 36 | if (m_count < N) 37 | ++m_count; 38 | // return average of current items 39 | return m_sum / m_count; 40 | } 41 | inline void reset() 42 | { 43 | m_count = 0; 44 | m_sum = 0; 45 | m_index = 0; 46 | } 47 | inline int count() { return m_count; } 48 | inline int sum() { return m_sum; } 49 | T oldest() 50 | { 51 | // undefined if nothing in here, return zero 52 | if (m_count == 0) 53 | return 0; 54 | // if it is not full, oldest is at index 0 55 | // if full, it is right where the next one goes 56 | if (m_count < N) 57 | return m_buffer[0]; 58 | else 59 | return m_buffer[m_index]; 60 | } 61 | T newest() 62 | { 63 | // undefined if nothing in here, return zero 64 | if (m_count == 0) 65 | return 0; 66 | // newest is index - 1, with wrap 67 | int index = m_index; 68 | if (--index < 0) 69 | index = m_count-1; 70 | return m_buffer[index]; 71 | } 72 | T average() 73 | { 74 | if (m_count == 0) 75 | return 0; 76 | return m_sum / m_count; 77 | } 78 | }; 79 | 80 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 81 | // DecayingAverage Class Declaration 82 | // 83 | 84 | template 85 | class DecayingAverage 86 | { 87 | private: 88 | T m_last; 89 | bool m_lastvalid; 90 | 91 | public: 92 | inline DecayingAverage() { reset(); } 93 | T filter(T data, int fingers) 94 | { 95 | TT result = data; 96 | TT last = m_last; 97 | if (m_lastvalid) 98 | result = (result * N1) / D + (last * N2) / D; 99 | m_lastvalid = true; 100 | m_last = (T)result; 101 | return m_last; 102 | } 103 | inline void reset() 104 | { 105 | m_lastvalid = false; 106 | } 107 | }; 108 | 109 | template 110 | class UndecayAverage 111 | { 112 | private: 113 | T m_last; 114 | bool m_lastvalid; 115 | 116 | public: 117 | inline UndecayAverage() { reset(); } 118 | T filter(T data) 119 | { 120 | TT result = data; 121 | TT last = m_last; 122 | if (m_lastvalid) 123 | result = (result * D) / N1 - (last * N2) / N1; 124 | m_lastvalid = true; 125 | m_last = (T)data; 126 | return (T)result; 127 | } 128 | inline void reset() 129 | { 130 | m_lastvalid = false; 131 | } 132 | }; 133 | 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /VoodooPS2Trackpad/VoodooPS2TouchPadBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Brandon Pedersen on 5/1/13. 3 | // 4 | 5 | #ifndef __VoodooPS2TouchPadBase_H_ 6 | #define __VoodooPS2TouchPadBase_H_ 7 | 8 | #include "ApplePS2MouseDevice.h" 9 | #include 10 | #include 11 | #include 12 | #include "Decay.h" 13 | 14 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 15 | // VoodooPS2TouchPadBase Class Declaration 16 | // 17 | 18 | #define kPacketLength 6 19 | 20 | class EXPORT VoodooPS2TouchPadBase : public IOHIPointing 21 | { 22 | typedef IOHIPointing super; 23 | OSDeclareAbstractStructors(VoodooPS2TouchPadBase); 24 | 25 | protected: 26 | ApplePS2MouseDevice * _device; 27 | bool _interruptHandlerInstalled; 28 | bool _powerControlHandlerInstalled; 29 | bool _messageHandlerInstalled; 30 | RingBuffer _ringBuffer; 31 | UInt32 _packetByteCount; 32 | UInt8 _lastdata; 33 | UInt16 _touchPadVersion; 34 | 35 | IOCommandGate* _cmdGate; 36 | int z_finger; 37 | int divisorx, divisory; 38 | int ledge; 39 | int redge; 40 | int tedge; 41 | int bedge; 42 | int vscrolldivisor, hscrolldivisor, cscrolldivisor; 43 | int ctrigger; 44 | int centerx; 45 | int centery; 46 | uint64_t maxtaptime; 47 | uint64_t maxdragtime; 48 | uint64_t maxdbltaptime; 49 | int hsticky,vsticky, wsticky, tapstable; 50 | int wlimit, wvdivisor, whdivisor; 51 | bool clicking; 52 | bool dragging; 53 | int threefingervertswipe; 54 | int threefingerhorizswipe; 55 | bool draglock; 56 | int draglocktemp; 57 | bool hscroll, vscroll, scroll; 58 | bool rtap; 59 | bool outzone_wt, palm, palm_wt; 60 | int zlimit; 61 | int noled; 62 | uint64_t maxaftertyping; 63 | int mousemultiplierx, mousemultipliery; 64 | int mousescrollmultiplierx, mousescrollmultipliery; 65 | int mousemiddlescroll; 66 | int wakedelay; 67 | int smoothinput; 68 | int unsmoothinput; 69 | int skippassthru; 70 | int tapthreshx, tapthreshy; 71 | int dblthreshx, dblthreshy; 72 | int zonel, zoner, zonet, zoneb; 73 | int diszl, diszr, diszt, diszb; 74 | int diszctrl; // 0=automatic (ledpresent), 1=enable always, -1=disable always 75 | int _resolution, _scrollresolution; 76 | int swipedx, swipedy; 77 | int _buttonCount; 78 | int swapdoubletriple; 79 | int draglocktempmask; 80 | uint64_t clickpadclicktime; 81 | int clickpadtrackboth; 82 | int ignoredeltasstart; 83 | int bogusdxthresh, bogusdythresh; 84 | int scrolldxthresh, scrolldythresh; 85 | int immediateclick; 86 | 87 | // three finger and four finger state 88 | uint8_t inSwipeLeft, inSwipeRight; 89 | uint8_t inSwipeUp, inSwipeDown; 90 | uint8_t inSwipe4Left, inSwipe4Right; 91 | uint8_t inSwipe4Up, inSwipe4Down; 92 | int xmoved, ymoved; 93 | 94 | int rczl, rczr, rczb, rczt; // rightclick zone for 1-button ClickPads 95 | 96 | // state related to secondary packets/extendedwmode 97 | int lastx2, lasty2; 98 | bool tracksecondary; 99 | int xrest2, yrest2; 100 | bool clickedprimary; 101 | bool _extendedwmode; 102 | 103 | // normal state 104 | int lastx, lasty, last_fingers, b4last; 105 | UInt32 lastbuttons; 106 | int ignoredeltas; 107 | int xrest, yrest, scrollrest; 108 | int touchx, touchy; 109 | uint64_t touchtime; 110 | uint64_t untouchtime; 111 | bool wasdouble,wastriple; 112 | uint64_t keytime; 113 | bool ignoreall; 114 | UInt32 passbuttons; 115 | #ifdef SIMULATE_PASSTHRU 116 | UInt32 trackbuttons; 117 | #endif 118 | bool passthru; 119 | bool ledpresent; 120 | bool _reportsv; 121 | int clickpadtype; //0=not, 1=1button, 2=2button, 3=reserved 122 | UInt32 _clickbuttons; //clickbuttons to merge into buttons 123 | int mousecount; 124 | bool usb_mouse_stops_trackpad; 125 | 126 | int _modifierdown; // state of left+right control keys 127 | int scrollzoommask; 128 | 129 | // for scaling x/y values 130 | int xupmm, yupmm; 131 | 132 | // for middle button simulation 133 | enum mbuttonstate 134 | { 135 | STATE_NOBUTTONS, 136 | STATE_MIDDLE, 137 | STATE_WAIT4TWO, 138 | STATE_WAIT4NONE, 139 | STATE_NOOP, 140 | } _mbuttonstate; 141 | 142 | UInt32 _pendingbuttons; 143 | uint64_t _buttontime; 144 | IOTimerEventSource* _buttonTimer; 145 | uint64_t _maxmiddleclicktime; 146 | int _fakemiddlebutton; 147 | 148 | // momentum scroll state 149 | bool momentumscroll; 150 | SimpleAverage dy_history; 151 | SimpleAverage time_history; 152 | IOTimerEventSource* scrollTimer; 153 | uint64_t momentumscrolltimer; 154 | int momentumscrollthreshy; 155 | uint64_t momentumscrollinterval; 156 | int momentumscrollsum; 157 | int64_t momentumscrollcurrent; 158 | int64_t momentumscrollrest1; 159 | int momentumscrollmultiplier; 160 | int momentumscrolldivisor; 161 | int momentumscrollrest2; 162 | int momentumscrollsamplesmin; 163 | 164 | // timer for drag delay 165 | uint64_t dragexitdelay; 166 | IOTimerEventSource* dragTimer; 167 | 168 | SimpleAverage x_avg; 169 | SimpleAverage y_avg; 170 | //DecayingAverage x_avg; 171 | //DecayingAverage y_avg; 172 | UndecayAverage x_undo; 173 | UndecayAverage y_undo; 174 | 175 | SimpleAverage x2_avg; 176 | SimpleAverage y2_avg; 177 | //DecayingAverage x2_avg; 178 | //DecayingAverage y2_avg; 179 | UndecayAverage x2_undo; 180 | UndecayAverage y2_undo; 181 | 182 | enum 183 | { 184 | // "no touch" modes... must be even (see isTouchMode) 185 | MODE_NOTOUCH = 0, 186 | MODE_PREDRAG = 2, 187 | MODE_DRAGNOTOUCH = 4, 188 | 189 | // "touch" modes... must be odd (see isTouchMode) 190 | MODE_MOVE = 1, 191 | MODE_VSCROLL = 3, 192 | MODE_HSCROLL = 5, 193 | MODE_CSCROLL = 7, 194 | MODE_MTOUCH = 9, 195 | MODE_DRAG = 11, 196 | MODE_DRAGLOCK = 13, 197 | 198 | // special modes for double click in LED area to enable/disable 199 | // same "touch"/"no touch" odd/even rule (see isTouchMode) 200 | MODE_WAIT1RELEASE = 101, // "touch" 201 | MODE_WAIT2TAP = 102, // "no touch" 202 | MODE_WAIT2RELEASE = 103, // "touch" 203 | } touchmode; 204 | 205 | inline bool isTouchMode() { return touchmode & 1; } 206 | 207 | inline bool isInDisableZone(int x, int y) 208 | { return x > diszl && x < diszr && y > diszb && y < diszt; } 209 | 210 | // Sony: coordinates captured from single touch event 211 | // Don't know what is the exact value of x and y on edge of touchpad 212 | // the best would be { return x > xmax/2 && y < ymax/4; } 213 | 214 | inline bool isInRightClickZone(int x, int y) 215 | { return x > rczl && x < rczr && y > rczb && y < rczt; } 216 | 217 | virtual void setTouchPadEnable( bool enable ) = 0; 218 | virtual PS2InterruptResult interruptOccurred(UInt8 data) = 0; 219 | virtual void packetReady() = 0; 220 | virtual void setDevicePowerState(UInt32 whatToDo); 221 | 222 | virtual void receiveMessage(int message, void* data); 223 | 224 | virtual void touchpadToggled() {}; 225 | virtual void touchpadShutdown() {}; 226 | virtual void initTouchPad(); 227 | 228 | inline bool isFingerTouch(int z) { return z>z_finger && zsetTimeout(*(AbsoluteTime*)&time); } 248 | inline void cancelTimer(IOTimerEventSource* timer) 249 | { timer->cancelTimeout(); } 250 | 251 | public: 252 | virtual bool init( OSDictionary * properties ); 253 | virtual VoodooPS2TouchPadBase * probe( IOService * provider, 254 | SInt32 * score ) = 0; 255 | virtual bool start( IOService * provider ); 256 | virtual void stop( IOService * provider ); 257 | 258 | virtual UInt32 deviceType(); 259 | virtual UInt32 interfaceID(); 260 | 261 | virtual IOReturn setParamProperties(OSDictionary * dict); 262 | virtual IOReturn setProperties(OSObject *props); 263 | }; 264 | 265 | #endif //__VoodooPS2TouchPadBase_H_ 266 | -------------------------------------------------------------------------------- /VoodooPS2Trackpad/VoodooPS2Trackpad-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleExecutable 6 | VoodooPS2Trackpad 7 | CFBundleGetInfoString 8 | ${MODULE_VERSION}, Copyright Apple Computer, Inc. 2002-2003, mackerintel 2008, RehabMan 2012-2013, Dr Hurt 2016 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Voodoo PS/2 Trackpad 15 | CFBundlePackageType 16 | KEXT 17 | CFBundleShortVersionString 18 | ${MODULE_VERSION} 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${MODULE_VERSION} 23 | IOKitPersonalities 24 | 25 | ALPS TouchPad 26 | 27 | SupportsGestureScrolling 28 | 29 | TrackpadFourFingerGestures 30 | 31 | ApplePreferenceIdentifier 32 | com.apple.AppleMultitouchTrackpad 33 | MTHIDDevice 34 | 35 | MT Built-in 36 | 37 | ApplePreferenceCapability 38 | 39 | TrackpadEmbedded 40 | 41 | TrackpadThreeFingerDrag 42 | 43 | TrackpadSecondaryClickCorners 44 | 45 | CFBundleIdentifier 46 | org.rehabman.voodoo.driver.PS2Trackpad 47 | IOClass 48 | ALPS 49 | IOProbeScore 50 | 6000 51 | IOProviderClass 52 | ApplePS2MouseDevice 53 | Platform Profile 54 | 55 | Default 56 | 57 | BogusDeltaThreshX 58 | 0 59 | BogusDeltaThreshY 60 | 0 61 | CenterX 62 | 3000 63 | CenterY 64 | 2100 65 | CircularScrollDivisor 66 | 0 67 | CircularScrollTrigger 68 | 0 69 | DisableDevice 70 | 71 | DisableLEDUpdating 72 | 73 | DivisorX 74 | 5 75 | DivisorY 76 | 5 77 | DoubleTapThresholdX 78 | 100 79 | DoubleTapThresholdY 80 | 100 81 | DragExitDelayTime 82 | 1000000000 83 | DragLockTempMask 84 | 1048592 85 | DoubleSmoothness 86 | 87 | EdgeBottom 88 | 500 89 | EdgeLeft 90 | 1700 91 | EdgeRight 92 | 5200 93 | EdgeTop 94 | 2940 95 | FingerChangeIgnoreDeltas 96 | 0 97 | FingerZ 98 | 30 99 | HorizontalScrollDivisor 100 | 0 101 | ImmediateClick 102 | 103 | MaxDragTime 104 | 180000000 105 | MaxTapTime 106 | 130000000 107 | MomentumScrollDivisor 108 | 100 109 | MomentumScrollMultiplier 110 | 98 111 | MomentumScrollSamplesMin 112 | 3 113 | MomentumScrollThreshY 114 | 7 115 | MomentumScrollTimer 116 | 10000000 117 | MultiFingerHorizontalDivisor 118 | 5 119 | MultiFingerVerticalDivisor 120 | 5 121 | QuietTimeAfterTyping 122 | 500000000 123 | Resolution 124 | 400 125 | ScrollDeltaThreshX 126 | 0 127 | ScrollDeltaThreshY 128 | 0 129 | ScrollResolution 130 | 400 131 | SmoothInput 132 | 133 | StickyHorizontalScrolling 134 | 135 | StickyMultiFingerScrolling 136 | 137 | StickyVerticalScrolling 138 | 139 | SwapDoubleTriple 140 | 141 | SwipeDeltaX 142 | 400 143 | SwipeDeltaY 144 | 400 145 | TapThresholdX 146 | 50 147 | TapThresholdY 148 | 50 149 | USBMouseStopsTrackpad 150 | 0 151 | UnitsPerMMX 152 | 50 153 | UnitsPerMMY 154 | 50 155 | UnsmoothInput 156 | 157 | VerticalScrollDivisor 158 | 0 159 | WakeDelay 160 | 1000 161 | ZLimit 162 | 255 163 | ZoneBottom 164 | 0 165 | ZoneLeft 166 | 567 167 | ZoneRight 168 | 1733 169 | ZoneTop 170 | 99999 171 | 172 | 173 | ProductID 174 | 547 175 | VendorID 176 | 1452 177 | 178 | 179 | OSBundleLibraries 180 | 181 | com.apple.iokit.IOHIDSystem 182 | 1.0.0b1 183 | com.apple.kpi.iokit 184 | 9.0.0 185 | com.apple.kpi.libkern 186 | 9.0.0 187 | com.apple.kpi.mach 188 | 9.0.0 189 | org.rehabman.voodoo.driver.PS2Controller 190 | 2.8.15 191 | 192 | OSBundleRequired 193 | Console 194 | Source Code 195 | https://github.com/SergeySlice/OS-X-ALPS-DRIVER 196 | 197 | 198 | -------------------------------------------------------------------------------- /VoodooPS2Trackpad/VoodooPS2Trackpad-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'VoodooPS2Trackpad' target in the 'VoodooPS2Trackpad' project 3 | // 4 | 5 | -------------------------------------------------------------------------------- /VoodooPS2Trackpad/alps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.2 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | 23 | #include "VoodooPS2TouchPadBase.h" 24 | 25 | #define ALPS_PROTO_V1 0x100 26 | #define ALPS_PROTO_V2 0x200 27 | #define ALPS_PROTO_V3 0x300 28 | #define ALPS_PROTO_V3_RUSHMORE 0x310 29 | #define ALPS_PROTO_V4 0x400 30 | #define ALPS_PROTO_V5 0x500 31 | #define ALPS_PROTO_V6 0x600 32 | #define ALPS_PROTO_V7 0x700 /* t3btl t4s */ 33 | #define ALPS_PROTO_V8 0x800 /* SS4btl SS4s */ 34 | 35 | #define MAX_TOUCHES 4 36 | 37 | #define DOLPHIN_COUNT_PER_ELECTRODE 64 38 | #define DOLPHIN_PROFILE_XOFFSET 8 /* x-electrode offset */ 39 | #define DOLPHIN_PROFILE_YOFFSET 1 /* y-electrode offset */ 40 | 41 | /* 42 | * enum SS4_PACKET_ID - defines the packet type for V8 43 | * SS4_PACKET_ID_IDLE: There's no finger and no button activity. 44 | * SS4_PACKET_ID_ONE: There's one finger on touchpad 45 | * or there's button activities. 46 | * SS4_PACKET_ID_TWO: There's two or more fingers on touchpad 47 | * SS4_PACKET_ID_MULTI: There's three or more fingers on touchpad 48 | */ 49 | enum SS4_PACKET_ID { 50 | SS4_PACKET_ID_IDLE = 0, 51 | SS4_PACKET_ID_ONE, 52 | SS4_PACKET_ID_TWO, 53 | SS4_PACKET_ID_MULTI, 54 | SS4_PACKET_ID_STICK, 55 | }; 56 | 57 | #define SS4_COUNT_PER_ELECTRODE 256 58 | #define SS4_NUMSENSOR_XOFFSET 7 59 | #define SS4_NUMSENSOR_YOFFSET 7 60 | #define SS4_MIN_PITCH_MM 50 61 | 62 | #define SS4_MASK_NORMAL_BUTTONS 0x07 63 | 64 | #define SS4_1F_X_V2(_b) ((_b[0] & 0x0007) | \ 65 | ((_b[1] << 3) & 0x0078) | \ 66 | ((_b[1] << 2) & 0x0380) | \ 67 | ((_b[2] << 5) & 0x1C00) \ 68 | ) 69 | 70 | #define SS4_1F_Y_V2(_b) (((_b[2]) & 0x000F) | \ 71 | ((_b[3] >> 2) & 0x0030) | \ 72 | ((_b[4] << 6) & 0x03C0) | \ 73 | ((_b[4] << 5) & 0x0C00) \ 74 | ) 75 | 76 | #define SS4_1F_Z_V2(_b) (((_b[5]) & 0x0F) | \ 77 | ((_b[5] >> 1) & 0x70) | \ 78 | ((_b[4]) & 0x80) \ 79 | ) 80 | 81 | #define SS4_1F_LFB_V2(_b) (((_b[2] >> 4) & 0x01) == 0x01) 82 | 83 | #define SS4_MF_LF_V2(_b, _i) ((_b[1 + (_i) * 3] & 0x0004) == 0x0004) 84 | 85 | #define SS4_BTN_V2(_b) ((_b[0] >> 5) & SS4_MASK_NORMAL_BUTTONS) 86 | 87 | #define SS4_STD_MF_X_V2(_b, _i) (((_b[0 + (_i) * 3] << 5) & 0x00E0) | \ 88 | ((_b[1 + _i * 3] << 5) & 0x1F00) \ 89 | ) 90 | 91 | #define SS4_STD_MF_Y_V2(_b, _i) (((_b[1 + (_i) * 3] << 3) & 0x0010) | \ 92 | ((_b[2 + (_i) * 3] << 5) & 0x01E0) | \ 93 | ((_b[2 + (_i) * 3] << 4) & 0x0E00) \ 94 | ) 95 | 96 | #define SS4_BTL_MF_X_V2(_b, _i) (SS4_STD_MF_X_V2(_b, _i) | \ 97 | ((_b[0 + (_i) * 3] >> 3) & 0x0010) \ 98 | ) 99 | 100 | #define SS4_BTL_MF_Y_V2(_b, _i) (SS4_STD_MF_Y_V2(_b, _i) | \ 101 | ((_b[0 + (_i) * 3] >> 3) & 0x0008) \ 102 | ) 103 | 104 | #define SS4_MF_Z_V2(_b, _i) (((_b[1 + (_i) * 3]) & 0x0001) | \ 105 | ((_b[1 + (_i) * 3] >> 1) & 0x0002) \ 106 | ) 107 | 108 | #define SS4_IS_MF_CONTINUE(_b) ((_b[2] & 0x10) == 0x10) 109 | #define SS4_IS_5F_DETECTED(_b) ((_b[2] & 0x10) == 0x10) 110 | 111 | 112 | #define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */ 113 | #define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */ 114 | #define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coordinate value */ 115 | #define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coordinate value */ 116 | 117 | /* 118 | * enum V7_PACKET_ID - defines the packet type for V7 119 | * V7_PACKET_ID_IDLE: There's no finger and no button activity. 120 | * V7_PACKET_ID_TWO: There's one or two non-resting fingers on touchpad 121 | * or there's button activities. 122 | * V7_PACKET_ID_MULTI: There are at least three non-resting fingers. 123 | * V7_PACKET_ID_NEW: The finger position in slot is not continues from 124 | * previous packet. 125 | */ 126 | enum V7_PACKET_ID { 127 | V7_PACKET_ID_IDLE, 128 | V7_PACKET_ID_TWO, 129 | V7_PACKET_ID_MULTI, 130 | V7_PACKET_ID_NEW, 131 | V7_PACKET_ID_UNKNOWN, 132 | }; 133 | 134 | 135 | /** 136 | * struct alps_model_info - touchpad ID table 137 | * @signature: E7 response string to match. 138 | * @command_mode_resp: For V3/V4 touchpads, the final byte of the EC response 139 | * (aka command mode response) identifies the firmware minor version. This 140 | * can be used to distinguish different hardware models which are not 141 | * uniquely identifiable through their E7 responses. 142 | * @proto_version: Indicates V1/V2/V3/... 143 | * @byte0: Helps figure out whether a position report packet matches the 144 | * known format for this model. The first byte of the report, ANDed with 145 | * mask0, should match byte0. 146 | * @mask0: The mask used to check the first byte of the report. 147 | * @flags: Additional device capabilities (passthrough port, trackstick, etc.). 148 | * 149 | * Many (but not all) ALPS touchpads can be identified by looking at the 150 | * values returned in the "E7 report" and/or the "EC report." This table 151 | * lists a number of such touchpads. 152 | */ 153 | struct alps_model_info { 154 | UInt8 signature[3]; 155 | UInt8 command_mode_resp; 156 | UInt16 proto_version; 157 | UInt8 byte0, mask0; 158 | unsigned int flags; 159 | }; 160 | 161 | /** 162 | * struct alps_nibble_commands - encodings for register accesses 163 | * @command: PS/2 command used for the nibble 164 | * @data: Data supplied as an argument to the PS/2 command, if applicable 165 | * 166 | * The ALPS protocol uses magic sequences to transmit binary data to the 167 | * touchpad, as it is generally not OK to send arbitrary bytes out the 168 | * PS/2 port. Each of the sequences in this table sends one nibble of the 169 | * register address or (write) data. Different versions of the ALPS protocol 170 | * use slightly different encodings. 171 | */ 172 | struct alps_nibble_commands { 173 | SInt32 command; 174 | UInt8 data; 175 | }; 176 | 177 | struct alps_bitmap_point { 178 | int start_bit; 179 | int num_bits; 180 | }; 181 | 182 | struct input_mt_pos { 183 | UInt32 x; 184 | UInt32 y; 185 | }; 186 | 187 | /** 188 | * struct alps_fields - decoded version of the report packet 189 | * @x_map: Bitmap of active X positions for MT. 190 | * @y_map: Bitmap of active Y positions for MT. 191 | * @fingers: Number of fingers for MT. 192 | * @pressure: Pressure. 193 | * @st: position for ST. 194 | * @mt: position for MT. 195 | * @first_mp: Packet is the first of a multi-packet report. 196 | * @is_mp: Packet is part of a multi-packet report. 197 | * @left: Left touchpad button is active. 198 | * @right: Right touchpad button is active. 199 | * @middle: Middle touchpad button is active. 200 | * @ts_left: Left trackstick button is active. 201 | * @ts_right: Right trackstick button is active. 202 | * @ts_middle: Middle trackstick button is active. 203 | */ 204 | struct alps_fields { 205 | UInt32 x_map; 206 | UInt32 y_map; 207 | UInt32 fingers; 208 | 209 | int pressure; 210 | struct input_mt_pos st; 211 | struct input_mt_pos mt[MAX_TOUCHES]; 212 | 213 | UInt32 first_mp:1; 214 | UInt32 is_mp:1; 215 | 216 | UInt32 left:1; 217 | UInt32 right:1; 218 | UInt32 middle:1; 219 | 220 | UInt32 ts_left:1; 221 | UInt32 ts_right:1; 222 | UInt32 ts_middle:1; 223 | }; 224 | 225 | class ALPS; 226 | 227 | /** 228 | * struct alps_data - private data structure for the ALPS driver 229 | * @nibble_commands: Command mapping used for touchpad register accesses. 230 | * @addr_command: Command used to tell the touchpad that a register address 231 | * follows. 232 | * @proto_version: Indicates V1/V2/V3/... 233 | * @byte0: Helps figure out whether a position report packet matches the 234 | * known format for this model. The first byte of the report, ANDed with 235 | * mask0, should match byte0. 236 | * @mask0: The mask used to check the first byte of the report. 237 | * @fw_ver: cached copy of firmware version (EC report) 238 | * @flags: Additional device capabilities (passthrough port, trackstick, etc.). 239 | * @x_max: Largest possible X position value. 240 | * @y_max: Largest possible Y position value. 241 | * @x_bits: Number of X bits in the MT bitmap. 242 | * @y_bits: Number of Y bits in the MT bitmap. 243 | * @prev_fin: Finger bit from previous packet. 244 | * @multi_packet: Multi-packet data in progress. 245 | * @multi_data: Saved multi-packet data. 246 | * @f: Decoded packet data fields. 247 | * @quirks: Bitmap of ALPS_QUIRK_*. 248 | */ 249 | struct alps_data { 250 | /* these are autodetected when the device is identified */ 251 | const struct alps_nibble_commands *nibble_commands; 252 | SInt32 addr_command; 253 | UInt16 proto_version; 254 | UInt8 byte0, mask0; 255 | UInt8 fw_ver[3]; 256 | int flags; 257 | SInt32 x_max; 258 | SInt32 y_max; 259 | SInt32 x_bits; 260 | SInt32 y_bits; 261 | unsigned int x_res; 262 | unsigned int y_res; 263 | 264 | SInt32 prev_fin; 265 | SInt32 multi_packet; 266 | int second_touch; 267 | UInt8 multi_data[6]; 268 | struct alps_fields f; 269 | UInt8 quirks; 270 | bool PSMOUSE_BAD_DATA; 271 | 272 | int pktsize = 6; 273 | }; 274 | 275 | // Pulled out of alps_data, now saved as vars on class 276 | // makes invoking a little easier 277 | typedef bool (ALPS::*hw_init)(); 278 | typedef bool (ALPS::*decode_fields)(struct alps_fields *f, UInt8 *p); 279 | typedef void (ALPS::*process_packet)(UInt8 *packet); 280 | //typedef void (ALPS::*set_abs_params)(); 281 | 282 | #define ALPS_QUIRK_TRACKSTICK_BUTTONS 1 /* trakcstick buttons in trackstick packet */ 283 | 284 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 285 | // ALPS Class Declaration 286 | // 287 | 288 | typedef struct ALPSStatus { 289 | UInt8 bytes[3]; 290 | } ALPSStatus_t; 291 | 292 | #define kPacketLengthSmall 3 293 | #define kPacketLengthLarge 6 294 | #define kPacketLengthMax 6 295 | #define kDP_CommandNibble10 0xf2 296 | #define BITS_PER_BYTE 8 297 | 298 | // predeclure stuff 299 | struct alps_data; 300 | 301 | class EXPORT ALPS : public VoodooPS2TouchPadBase { 302 | typedef VoodooPS2TouchPadBase super; 303 | OSDeclareDefaultStructors( ALPS ); 304 | 305 | private: 306 | alps_data priv; 307 | hw_init hw_init; 308 | decode_fields decode_fields; 309 | process_packet process_packet; 310 | // set_abs_params set_abs_params; 311 | 312 | public: 313 | virtual ALPS * probe(IOService *provider, SInt32 *score); 314 | 315 | bool init(OSDictionary * dict); 316 | 317 | void stop(IOService *provider); 318 | 319 | protected: 320 | int _multiPacket; 321 | 322 | UInt8 _multiData[6]; 323 | 324 | IOGBounds _bounds; 325 | 326 | virtual bool deviceSpecificInit(); 327 | 328 | bool resetMouse(); 329 | 330 | void alps_process_packet_v1_v2(UInt8 *packet); 331 | 332 | int alps_process_bitmap(struct alps_data *priv, struct alps_fields *f); 333 | 334 | void alps_process_trackstick_packet_v3(UInt8 * packet); 335 | 336 | bool alps_decode_buttons_v3(struct alps_fields *f, UInt8 *p); 337 | 338 | bool alps_decode_pinnacle(struct alps_fields *f, UInt8 *p); 339 | 340 | bool alps_decode_rushmore(struct alps_fields *f, UInt8 *p); 341 | 342 | bool alps_decode_dolphin(struct alps_fields *f, UInt8 *p); 343 | 344 | void alps_process_touchpad_packet_v3_v5(UInt8 * packet); 345 | 346 | void alps_process_packet_v3(UInt8 *packet); 347 | 348 | void alps_process_packet_v6(UInt8 *packet); 349 | 350 | void alps_process_packet_v4(UInt8 *packet); 351 | 352 | unsigned char alps_get_packet_id_v7(UInt8 *byte); 353 | 354 | void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, UInt8 *pkt, UInt8 pkt_id); 355 | 356 | int alps_get_mt_count(struct input_mt_pos *mt); 357 | 358 | bool alps_decode_packet_v7(struct alps_fields *f, UInt8 *p); 359 | 360 | void alps_process_trackstick_packet_v7(UInt8 *packet); 361 | 362 | void alps_process_touchpad_packet_v7(UInt8 *packet); 363 | 364 | void alps_process_packet_v7(UInt8 *packet); 365 | 366 | unsigned char alps_get_pkt_id_ss4_v2(UInt8 *byte); 367 | 368 | bool alps_decode_ss4_v2(struct alps_fields *f, UInt8 *p); 369 | 370 | void alps_process_packet_ss4_v2(UInt8 *packet); 371 | 372 | void dispatchEventsWithInfo(int xraw, int yraw, int z, int fingers, UInt32 buttonsraw); 373 | 374 | virtual void dispatchRelativePointerEventWithPacket(UInt8 *packet, UInt32 packetSize); 375 | 376 | void setTouchPadEnable(bool enable); 377 | 378 | PS2InterruptResult interruptOccurred(UInt8 data); 379 | 380 | void packetReady(); 381 | 382 | bool alps_command_mode_send_nibble(int value); 383 | 384 | bool alps_command_mode_set_addr(int addr); 385 | 386 | int alps_command_mode_read_reg(int addr); 387 | 388 | bool alps_command_mode_write_reg(int addr, UInt8 value); 389 | 390 | bool alps_command_mode_write_reg(UInt8 value); 391 | 392 | bool alps_rpt_cmd(SInt32 init_command, SInt32 init_arg, SInt32 repeated_command, ALPSStatus_t *report); 393 | 394 | bool alps_enter_command_mode(); 395 | 396 | bool alps_exit_command_mode(); 397 | 398 | bool alps_passthrough_mode_v2(bool enable); 399 | 400 | bool alps_absolute_mode_v1_v2(); 401 | 402 | int alps_monitor_mode_send_word(int word); 403 | 404 | int alps_monitor_mode_write_reg(int addr, int value); 405 | 406 | int alps_monitor_mode(bool enable); 407 | 408 | void alps_absolute_mode_v6(); 409 | 410 | bool alps_get_status(ALPSStatus_t *status); 411 | 412 | bool alps_tap_mode(bool enable); 413 | 414 | bool alps_hw_init_v1_v2(); 415 | 416 | bool alps_hw_init_v6(); 417 | 418 | bool alps_passthrough_mode_v3(int regBase, bool enable); 419 | 420 | bool alps_absolute_mode_v3(); 421 | 422 | IOReturn alps_probe_trackstick_v3_v7(int regBase); 423 | 424 | IOReturn alps_setup_trackstick_v3(int regBase); 425 | 426 | bool alps_hw_init_v3(); 427 | 428 | bool alps_get_v3_v7_resolution(int reg_pitch); 429 | 430 | bool alps_hw_init_rushmore_v3(); 431 | 432 | bool alps_absolute_mode_v4(); 433 | 434 | bool alps_hw_init_v4(); 435 | 436 | void alps_get_otp_values_ss4_v2(unsigned char index); 437 | 438 | void alps_set_defaults_ss4_v2(struct alps_data *priv); 439 | 440 | int alps_dolphin_get_device_area(struct alps_data *priv); 441 | 442 | bool alps_hw_init_dolphin_v1(); 443 | 444 | bool alps_hw_init_v7(); 445 | 446 | bool alps_hw_init_ss4_v2(); 447 | 448 | void ps2_command_short(UInt8 command); 449 | 450 | void ps2_command(unsigned char value, UInt8 command); 451 | 452 | void set_protocol(); 453 | 454 | bool matchTable(ALPSStatus_t *e7, ALPSStatus_t *ec); 455 | 456 | IOReturn identify(); 457 | 458 | void restart(); 459 | }; 460 | -------------------------------------------------------------------------------- /VoodooPS2Trackpad/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # really just some handy scripts... 2 | 3 | DIST=RehabMan-Voodoo 4 | INSTDIR=/System/Library/Extensions 5 | KEXT=VoodooPS2Controller.kext 6 | 7 | ifeq ($(findstring 32,$(BITS)),32) 8 | OPTIONS:=$(OPTIONS) -arch i386 9 | endif 10 | 11 | ifeq ($(findstring 64,$(BITS)),64) 12 | OPTIONS:=$(OPTIONS) -arch x86_64 13 | endif 14 | 15 | .PHONY: all 16 | all: 17 | xcodebuild build $(OPTIONS) -scheme All -configuration Debug 18 | xcodebuild build $(OPTIONS) -scheme All -configuration Release 19 | 20 | .PHONY: clean 21 | clean: 22 | xcodebuild clean $(OPTIONS) -scheme All -configuration Debug 23 | xcodebuild clean $(OPTIONS) -scheme All -configuration Release 24 | 25 | .PHONY: update_kernelcache 26 | update_kernelcache: 27 | sudo touch /System/Library/Extensions 28 | sudo kextcache -update-volume / 29 | 30 | .PHONY: rehabman_special_settings 31 | rehabman_special_settings: 32 | sudo /usr/libexec/PlistBuddy -c "Set ':IOKitPersonalities:Synaptics TouchPad:Platform Profile:Default:DragLockTempMask' 262148" $(INSTDIR)/$(KEXT)/Contents/PlugIns/VoodooPS2Trackpad.kext/Contents/Info.plist 33 | #sudo /usr/libexec/PlistBuddy -c "Set ':IOKitPersonalities:Synaptics TouchPad:Platform Profile:HPQOEM:ProBook:FingerZ' 47" $(INSTDIR)/$(KEXT)/Contents/PlugIns/VoodooPS2Trackpad.kext/Contents/Info.plist 34 | 35 | .PHONY: install_debug 36 | install_debug: 37 | sudo rm -Rf $(INSTDIR)/$(KEXT) 38 | sudo cp -R ./Build/Products/Debug/$(KEXT) $(INSTDIR) 39 | if [ "`which tag`" != "" ]; then sudo tag -a Purple $(INSTDIR)/$(KEXT); fi 40 | make rehabman_special_settings 41 | sudo cp ./VoodooPS2Daemon/org.rehabman.voodoo.driver.Daemon.plist /Library/LaunchDaemons 42 | sudo cp ./Build/Products/Debug/VoodooPS2Daemon /usr/bin 43 | if [ "`which tag`" != "" ]; then sudo tag -a Purple /usr/bin/VoodooPS2Daemon; fi 44 | make update_kernelcache 45 | 46 | .PHONY: install 47 | install: install_kext install_daemon 48 | 49 | .PHONY: install_kext 50 | install_kext: 51 | sudo rm -Rf $(INSTDIR)/$(KEXT) 52 | sudo cp -R ./Build/Products/Release/$(KEXT) $(INSTDIR) 53 | if [ "`which tag`" != "" ]; then sudo tag -a Blue $(INSTDIR)/$(KEXT); fi 54 | make rehabman_special_settings 55 | make update_kernelcache 56 | 57 | .PHONY: install_mouse 58 | install_mouse: 59 | sudo rm -Rf $(INSTDIR)/$(KEXT) 60 | sudo cp -R ./Build/Products/Release/$(KEXT) $(INSTDIR) 61 | if [ "`which tag`" != "" ]; then sudo tag -a Blue $(INSTDIR)/$(KEXT); fi 62 | sudo rm -R $(INSTDIR)/$(KEXT)/Contents/PlugIns/VoodooPS2Trackpad.kext 63 | sudo /usr/libexec/PlistBuddy -c "Set ':IOKitPersonalities:ApplePS2Mouse:Platform Profile:HPQOEM:ProBook:DisableDevice' No" $(INSTDIR)/$(KEXT)/Contents/PlugIns/VoodooPS2Mouse.kext/Contents/Info.plist 64 | make update_kernelcache 65 | 66 | .PHONY: install_mouse_debug 67 | install_mouse_debug: 68 | sudo rm -Rf $(INSTDIR)/$(KEXT) 69 | sudo cp -R ./Build/Products/Debug/$(KEXT) $(INSTDIR) 70 | if [ "`which tag`" != "" ]; then sudo tag -a Purple $(INSTDIR)/$(KEXT); fi 71 | sudo rm -R $(INSTDIR)/$(KEXT)/Contents/PlugIns/VoodooPS2Trackpad.kext 72 | sudo /usr/libexec/PlistBuddy -c "Set ':IOKitPersonalities:ApplePS2Mouse:Platform Profile:HPQOEM:ProBook:DisableDevice' No" $(INSTDIR)/$(KEXT)/Contents/PlugIns/VoodooPS2Mouse.kext/Contents/Info.plist 73 | make update_kernelcache 74 | 75 | .PHONY: install_daemon 76 | install_daemon: 77 | sudo cp ./VoodooPS2Daemon/org.rehabman.voodoo.driver.Daemon.plist /Library/LaunchDaemons 78 | sudo cp ./Build/Products/Release/VoodooPS2Daemon /usr/bin 79 | if [ "`which tag`" != "" ]; then sudo tag -a Blue /usr/bin/VoodooPS2Daemon; fi 80 | 81 | install.sh: makefile 82 | make -n install >install.sh 83 | chmod +x install.sh 84 | 85 | .PHONY: distribute 86 | distribute: 87 | if [ -e ./Distribute ]; then rm -r ./Distribute; fi 88 | mkdir ./Distribute 89 | cp -R ./Build/Products/ ./Distribute 90 | find ./Distribute -path *.DS_Store -delete 91 | find ./Distribute -path *.dSYM -exec echo rm -r {} \; >/tmp/org.voodoo.rm.dsym.sh 92 | chmod +x /tmp/org.voodoo.rm.dsym.sh 93 | /tmp/org.voodoo.rm.dsym.sh 94 | rm /tmp/org.voodoo.rm.dsym.sh 95 | cp ./VoodooPS2Daemon/org.rehabman.voodoo.driver.Daemon.plist ./Distribute/ 96 | rm -r ./Distribute/Debug/VoodooPS2synapticsPane.prefPane 97 | rm -r ./Distribute/Release/VoodooPS2synapticsPane.prefPane 98 | rm ./Distribute/Debug/synapticsconfigload 99 | rm ./Distribute/Release/synapticsconfigload 100 | ditto -c -k --sequesterRsrc --zlibCompressionLevel 9 ./Distribute ./Archive.zip 101 | mv ./Archive.zip ./Distribute/`date +$(DIST)-%Y-%m%d.zip` 102 | -------------------------------------------------------------------------------- /new_kext.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // new_kext.cpp 3 | // 4 | // Created by RehabMan on 2/3/13. 5 | // Copyright (c) 2013 rehabman. All rights reserved. 6 | // 7 | // Full complement of operator new/delete for use within kext environment. 8 | // 9 | 10 | #include "new_kext.h" 11 | 12 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 13 | 14 | // 15 | // Note: Originally these helper functions were exported as C++ functions 16 | // instead of extern "C", and they had much longer names. 17 | // 18 | // But that causes problems for Snow Leopard (crash using Kernel Cache at startup). 19 | // Not sure if it is related to the C++ names, or just the long names, but 20 | // this does work with the shorter extern "C" names, even on Snow Leopard. 21 | // 22 | // Also realize that the calls to IOMallocAligned/IOFreeAligned are mapped to 23 | // IOMalloc/IOFree because there appears to be a bug in the aligned variants. 24 | // See new_kext.h for the macros... 25 | // 26 | // Note: For now we are not using this code, as it is easier to just use the 27 | // built-in operator new/delete. I'm keeping it here, just in case it becomes 28 | // useful in the future. 29 | // 30 | 31 | extern "C" 32 | { 33 | 34 | void* _opnew(size_t size) 35 | { 36 | size_t* p = (size_t*)IOMallocAligned(sizeof(size_t) + size, sizeof(void*)); 37 | if (p) 38 | *p++ = size; 39 | return p; 40 | } 41 | 42 | void _opdel(void* p) 43 | { 44 | assert(p); 45 | if (p) 46 | { 47 | size_t* t = (size_t*)p-1; 48 | IOFreeAligned(t, *t); 49 | } 50 | } 51 | 52 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 53 | 54 | void* _opnewa(size_t size) 55 | { 56 | size_t* p = (size_t*)IOMallocAligned(sizeof(size_t) + size, sizeof(void*)); 57 | if (p) 58 | *p++ = size; 59 | return p; 60 | } 61 | 62 | void _opdela(void* p) 63 | { 64 | assert(p); 65 | if (p) 66 | { 67 | size_t* t = (size_t*)p-1; 68 | IOFreeAligned(t, *t); 69 | } 70 | } 71 | 72 | } // extern "C" 73 | 74 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 75 | 76 | -------------------------------------------------------------------------------- /new_kext.h: -------------------------------------------------------------------------------- 1 | // 2 | // new_kext.h 3 | // 4 | // Created by RehabMan on 2/3/13. 5 | // Copyright (c) 2013 rehabman. All rights reserved. 6 | // 7 | 8 | #ifndef _NEW_KEXT_H 9 | #define _NEW_KEXT_H 10 | 11 | #include 12 | 13 | extern "C" 14 | { 15 | // helper functions for export 16 | void* _opnew(size_t size); 17 | void _opdel(void* p); 18 | void* _opnewa(size_t size); 19 | void _opdela(void *p); 20 | } // extern "C" 21 | 22 | // placement new 23 | inline void* operator new(size_t, void* where) { return where; } 24 | 25 | // global scope new/delete 26 | inline void* operator new(size_t size) { return ::_opnew(size); } 27 | inline void operator delete(void* p) { return ::_opdel(p); } 28 | 29 | // global scope array new/delete 30 | inline void* operator new[](size_t size) { return ::_opnewa(size); } 31 | inline void operator delete[](void *p) { return ::_opdela(p); } 32 | 33 | //REVIEW: seems that IOMallocAligned is broken in OS X... don't use it for now! 34 | #define IOMallocAligned(x,y) IOMalloc(x) 35 | #define IOFreeAligned(x,y) IOFree(x,y) 36 | 37 | #endif // _NEW_KEXT_H 38 | --------------------------------------------------------------------------------