├── README.md ├── rt1015 ├── resource.h ├── rt1015.rc ├── spb.h ├── trace.h ├── rt1015.inf ├── rt1015.h ├── rt1015.vcxproj ├── spb.c ├── registers.h └── rt1015.c ├── rt1015.sln ├── LICENSE.txt ├── .gitignore └── rt1015 Package └── rt1015 Package.vcxproj /README.md: -------------------------------------------------------------------------------- 1 | # rt1015 2 | RT1015 Amplifier Driver 3 | 4 | Tested on Lenovo 300e Chromebook Gen 3. Should work for all vilboz chromebooks. -------------------------------------------------------------------------------- /rt1015/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by rt1015.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /rt1015/rt1015.rc: -------------------------------------------------------------------------------- 1 | /*++ 2 | 3 | Copyright (c) Microsoft Corporation All Rights Reserved 4 | 5 | Module Name: 6 | 7 | rt1015.rc 8 | 9 | Abstract: 10 | 11 | --*/ 12 | 13 | #include 14 | 15 | #define VER_FILETYPE VFT_DRV 16 | #define VER_FILESUBTYPE VFT2_DRV_SOUND 17 | #define VER_FILEDESCRIPTION_STR "Realtek ALC1015 I2S Amplifier" 18 | #define VER_INTERNALNAME_STR "rt1015.sys" 19 | #define VER_ORIGINALFILENAME_STR "rt1015.sys" 20 | 21 | #define VER_LEGALCOPYRIGHT_YEARS "2023" 22 | #define VER_LEGALCOPYRIGHT_STR "Copyright (C) " VER_LEGALCOPYRIGHT_YEARS " CoolStar." 23 | 24 | #define VER_FILEVERSION 1,0,1,0 25 | #define VER_PRODUCTVERSION_STR "1.0.1.0" 26 | #define VER_PRODUCTVERSION 1,0,1,0 27 | #define LVER_PRODUCTVERSION_STR L"1.0.1.0" 28 | 29 | #define VER_FILEFLAGSMASK (VS_FF_DEBUG | VS_FF_PRERELEASE) 30 | #ifdef DEBUG 31 | #define VER_FILEFLAGS (VS_FF_DEBUG) 32 | #else 33 | #define VER_FILEFLAGS (0) 34 | #endif 35 | 36 | #define VER_FILEOS VOS_NT_WINDOWS32 37 | 38 | #define VER_COMPANYNAME_STR "CoolStar" 39 | #define VER_PRODUCTNAME_STR "Realtek ALC1015 I2S Amplifier" 40 | 41 | #include "common.ver" -------------------------------------------------------------------------------- /rt1015/spb.h: -------------------------------------------------------------------------------- 1 | /*++ 2 | Copyright (c) Microsoft Corporation. All Rights Reserved. 3 | Sample code. Dealpoint ID #843729. 4 | 5 | Module Name: 6 | 7 | spb.h 8 | 9 | Abstract: 10 | 11 | This module contains the touch driver I2C helper definitions. 12 | 13 | Environment: 14 | 15 | Kernel Mode 16 | 17 | Revision History: 18 | 19 | --*/ 20 | 21 | #pragma once 22 | 23 | #include 24 | #include 25 | 26 | #define DEFAULT_SPB_BUFFER_SIZE 64 27 | #define RESHUB_USE_HELPER_ROUTINES 28 | 29 | // 30 | // SPB (I2C) context 31 | // 32 | 33 | typedef struct _SPB_CONTEXT 34 | { 35 | WDFIOTARGET SpbIoTarget; 36 | LARGE_INTEGER I2cResHubId; 37 | WDFMEMORY WriteMemory; 38 | WDFMEMORY ReadMemory; 39 | WDFWAITLOCK SpbLock; 40 | } SPB_CONTEXT; 41 | 42 | NTSTATUS 43 | SpbXferDataSynchronously( 44 | _In_ SPB_CONTEXT* SpbContext, 45 | _In_ PVOID SendData, 46 | _In_ ULONG SendLength, 47 | _In_reads_bytes_(Length) PVOID Data, 48 | _In_ ULONG Length 49 | ); 50 | 51 | VOID 52 | SpbTargetDeinitialize( 53 | IN WDFDEVICE FxDevice, 54 | IN SPB_CONTEXT* SpbContext 55 | ); 56 | 57 | NTSTATUS 58 | SpbTargetInitialize( 59 | IN WDFDEVICE FxDevice, 60 | IN SPB_CONTEXT* SpbContext 61 | ); 62 | 63 | NTSTATUS 64 | SpbWriteDataSynchronously( 65 | IN SPB_CONTEXT* SpbContext, 66 | IN PVOID Data, 67 | IN ULONG Length 68 | ); -------------------------------------------------------------------------------- /rt1015/trace.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef _TRACE_H_ 4 | #define _TRACE_H_ 5 | 6 | extern "C" 7 | { 8 | // 9 | // Tracing Definitions: 10 | // 11 | // Control GUID: 12 | // {73e3b785-f5fb-423e-94a9-56627fea9053} 13 | // 14 | 15 | #define WPP_CONTROL_GUIDS \ 16 | WPP_DEFINE_CONTROL_GUID( \ 17 | SpbTestToolTraceGuid, \ 18 | (73e3b785,f5fb,423e,94a9,56627fea9053), \ 19 | WPP_DEFINE_BIT(TRACE_FLAG_WDFLOADING) \ 20 | WPP_DEFINE_BIT(TRACE_FLAG_SPBAPI) \ 21 | WPP_DEFINE_BIT(TRACE_FLAG_OTHER) \ 22 | ) 23 | } 24 | 25 | #define WPP_LEVEL_FLAGS_LOGGER(level,flags) WPP_LEVEL_LOGGER(flags) 26 | #define WPP_LEVEL_FLAGS_ENABLED(level, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= level) 27 | 28 | #define Trace CyapaPrint 29 | #define FuncEntry 30 | #define FuncExit 31 | #define WPP_INIT_TRACING 32 | #define WPP_CLEANUP 33 | #define TRACE_FLAG_SPBAPI 0 34 | #define TRACE_FLAG_WDFLOADING 0 35 | 36 | // begin_wpp config 37 | // FUNC FuncEntry{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS); 38 | // FUNC FuncExit{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS); 39 | // USEPREFIX(FuncEntry, "%!STDPREFIX! [%!FUNC!] --> entry"); 40 | // USEPREFIX(FuncExit, "%!STDPREFIX! [%!FUNC!] <--"); 41 | // end_wpp 42 | 43 | #endif _TRACE_H_ 44 | -------------------------------------------------------------------------------- /rt1015/rt1015.inf: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ;Copyright (c) CoolStar. All rights reserved. 4 | ; 5 | ;Module Name: 6 | ; rt1015.inf 7 | ; 8 | ;Abstract: 9 | ; INF file for installing the Realtek ALC1015 I2S Amplifier Driver 10 | ; 11 | ; 12 | ;--*/ 13 | 14 | [Version] 15 | Signature = "$WINDOWS NT$" 16 | Class = Media 17 | ClassGuid = {4d36e96c-e325-11ce-bfc1-08002be10318} 18 | Provider = CoolStar 19 | DriverVer = 10/7/2022,1.0.0 20 | CatalogFile = rt1015.cat 21 | PnpLockdown=1 22 | 23 | [DestinationDirs] 24 | DefaultDestDir = 12 25 | 26 | ; ================= Class section ===================== 27 | 28 | [SourceDisksNames] 29 | 1 = %DiskId1%,,,"" 30 | 31 | [SourceDisksFiles] 32 | rt1015.sys = 1,, 33 | 34 | ;***************************************** 35 | ; rt1015 Install Section 36 | ;***************************************** 37 | 38 | [Manufacturer] 39 | %StdMfg%=Standard,NTAMD64 40 | 41 | ; Decorated model section take precedence over undecorated 42 | ; ones on XP and later. 43 | [Standard.NTAMD64] 44 | %rt1015.DeviceDesc%=Rt1015_Device, ACPI\10EC1015 45 | 46 | [Rt1015_Device.NT] 47 | CopyFiles=Drivers_Dir 48 | 49 | [Rt1015_Device.NT.HW] 50 | Include=pci.inf 51 | Needs=PciD3ColdSupported.HW 52 | 53 | [Drivers_Dir] 54 | rt1015.sys 55 | 56 | ;-------------- Service installation 57 | [Rt1015_Device.NT.Services] 58 | AddService = rt1015,%SPSVCINST_ASSOCSERVICE%, Rt1015_Service_Inst 59 | 60 | ; -------------- rt1015 driver install sections 61 | [Rt1015_Service_Inst] 62 | DisplayName = %rt1015.SVCDESC% 63 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 64 | StartType = 3 ; SERVICE_DEMAND_START 65 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 66 | ServiceBinary = %12%\rt1015.sys 67 | LoadOrderGroup = Base 68 | 69 | [Strings] 70 | SPSVCINST_ASSOCSERVICE= 0x00000002 71 | StdMfg = "CoolStar" 72 | DiskId1 = "Realtek 1015 Installation Disk #1" 73 | rt1015.DeviceDesc = "Realtek ALC1015 I2S Amplifier" 74 | rt1015.SVCDESC = "Realtek 1015 Service" 75 | -------------------------------------------------------------------------------- /rt1015.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32922.545 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rt1015", "rt1015\rt1015.vcxproj", "{36580C07-EDC3-4C2B-B45F-6AB017E01A5D}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rt1015 Package", "rt1015 Package\rt1015 Package.vcxproj", "{3DAE7ED3-003A-4495-8352-3D7B5B5D846F}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D} = {36580C07-EDC3-4C2B-B45F-6AB017E01A5D} 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Win32 = Debug|Win32 16 | Debug|x64 = Debug|x64 17 | Release|Win32 = Release|Win32 18 | Release|x64 = Release|x64 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Debug|Win32.ActiveCfg = Debug|Win32 22 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Debug|Win32.Build.0 = Debug|Win32 23 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Debug|Win32.Deploy.0 = Debug|Win32 24 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Debug|x64.ActiveCfg = Debug|x64 25 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Debug|x64.Build.0 = Debug|x64 26 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Debug|x64.Deploy.0 = Debug|x64 27 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Release|Win32.ActiveCfg = Release|Win32 28 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Release|Win32.Build.0 = Release|Win32 29 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Release|Win32.Deploy.0 = Release|Win32 30 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Release|x64.ActiveCfg = Release|x64 31 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Release|x64.Build.0 = Release|x64 32 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D}.Release|x64.Deploy.0 = Release|x64 33 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Debug|Win32.ActiveCfg = Debug|Win32 34 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Debug|Win32.Build.0 = Debug|Win32 35 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Debug|Win32.Deploy.0 = Debug|Win32 36 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Debug|x64.ActiveCfg = Debug|x64 37 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Debug|x64.Build.0 = Debug|x64 38 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Debug|x64.Deploy.0 = Debug|x64 39 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Release|Win32.ActiveCfg = Release|Win32 40 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Release|Win32.Build.0 = Release|Win32 41 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Release|Win32.Deploy.0 = Release|Win32 42 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Release|x64.ActiveCfg = Release|x64 43 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Release|x64.Build.0 = Release|x64 44 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F}.Release|x64.Deploy.0 = Release|x64 45 | EndGlobalSection 46 | GlobalSection(SolutionProperties) = preSolution 47 | HideSolutionNode = FALSE 48 | EndGlobalSection 49 | GlobalSection(ExtensibilityGlobals) = postSolution 50 | SolutionGuid = {9A2670CD-596B-41B9-958C-215F7069D30B} 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2021 CoolStar 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | 15 | 16 | ====================== Windows Driver Samples License ====================== 17 | 18 | The Microsoft Public License (MS-PL) 19 | Copyright (c) 2015 Microsoft 20 | 21 | This license governs use of the accompanying software. If you use the software, you 22 | accept this license. If you do not accept the license, do not use the software. 23 | 24 | 1. Definitions 25 | The terms "reproduce," "reproduction," "derivative works," and "distribution" have the 26 | same meaning here as under U.S. copyright law. 27 | A "contribution" is the original software, or any additions or changes to the software. 28 | A "contributor" is any person that distributes its contribution under this license. 29 | "Licensed patents" are a contributor's patent claims that read directly on its contribution. 30 | 31 | 2. Grant of Rights 32 | (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. 33 | (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 34 | 35 | 3. Conditions and Limitations 36 | (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. 37 | (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. 38 | (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. 39 | (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. 40 | (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. -------------------------------------------------------------------------------- /rt1015/rt1015.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RT1015_H_) 2 | #define _RT1015_H_ 3 | 4 | #pragma warning(disable:4200) // suppress nameless struct/union warning 5 | #pragma warning(disable:4201) // suppress nameless struct/union warning 6 | #pragma warning(disable:4214) // suppress bit field types other than int warning 7 | #include 8 | #include 9 | 10 | #pragma warning(default:4200) 11 | #pragma warning(default:4201) 12 | #pragma warning(default:4214) 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | #include "spb.h" 21 | 22 | // 23 | // String definitions 24 | // 25 | 26 | #define DRIVERNAME "rt1015.sys: " 27 | 28 | #define RT1015_POOL_TAG (ULONG) '5101' 29 | 30 | #define true 1 31 | #define false 0 32 | 33 | typedef enum { 34 | CSAudioEndpointTypeDSP, 35 | CSAudioEndpointTypeSpeaker, 36 | CSAudioEndpointTypeHeadphone, 37 | CSAudioEndpointTypeMicArray, 38 | CSAudioEndpointTypeMicJack 39 | } CSAudioEndpointType; 40 | 41 | typedef enum { 42 | CSAudioEndpointRegister, 43 | CSAudioEndpointStart, 44 | CSAudioEndpointStop, 45 | CSAudioEndpointOverrideFormat 46 | } CSAudioEndpointRequest; 47 | 48 | typedef struct CSAUDIOFORMATOVERRIDE { 49 | UINT16 channels; 50 | UINT16 frequency; 51 | UINT16 bitsPerSample; 52 | UINT16 validBitsPerSample; 53 | BOOLEAN force32BitOutputContainer; 54 | } CsAudioFormatOverride; 55 | 56 | typedef struct CSAUDIOARG { 57 | UINT32 argSz; 58 | CSAudioEndpointType endpointType; 59 | CSAudioEndpointRequest endpointRequest; 60 | union { 61 | CsAudioFormatOverride formatOverride; 62 | }; 63 | } CsAudioArg, * PCsAudioArg; 64 | 65 | typedef struct _RT1015_CONTEXT 66 | { 67 | 68 | WDFDEVICE FxDevice; 69 | 70 | WDFQUEUE ReportQueue; 71 | 72 | SPB_CONTEXT I2CContext; 73 | 74 | BOOLEAN SetUID; 75 | INT32 UID; 76 | 77 | BOOLEAN DevicePoweredOn; 78 | 79 | PCALLBACK_OBJECT CSAudioAPICallback; 80 | PVOID CSAudioAPICallbackObj; 81 | 82 | BOOLEAN CSAudioManaged; 83 | BOOLEAN CSAudioRequestsOn; 84 | 85 | } RT1015_CONTEXT, *PRT1015_CONTEXT; 86 | 87 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(RT1015_CONTEXT, GetDeviceContext) 88 | 89 | // 90 | // Function definitions 91 | // 92 | 93 | DRIVER_INITIALIZE DriverEntry; 94 | 95 | EVT_WDF_DRIVER_UNLOAD Rt1015DriverUnload; 96 | 97 | EVT_WDF_DRIVER_DEVICE_ADD Rt1015EvtDeviceAdd; 98 | 99 | EVT_WDFDEVICE_WDM_IRP_PREPROCESS Rt1015EvtWdmPreprocessMnQueryId; 100 | 101 | EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL Rt1015EvtInternalDeviceControl; 102 | 103 | // 104 | // Helper macros 105 | // 106 | 107 | #define DEBUG_LEVEL_ERROR 1 108 | #define DEBUG_LEVEL_INFO 2 109 | #define DEBUG_LEVEL_VERBOSE 3 110 | 111 | #define DBG_INIT 1 112 | #define DBG_PNP 2 113 | #define DBG_IOCTL 4 114 | 115 | #if 0 116 | #define Rt1015Print(dbglevel, dbgcatagory, fmt, ...) { \ 117 | if (Rt1015DebugLevel >= dbglevel && \ 118 | (Rt1015DebugCatagories && dbgcatagory)) \ 119 | { \ 120 | DbgPrint(DRIVERNAME); \ 121 | DbgPrint(fmt, __VA_ARGS__); \ 122 | } \ 123 | } 124 | #else 125 | #define Rt1015Print(dbglevel, fmt, ...) { \ 126 | } 127 | #endif 128 | 129 | #endif -------------------------------------------------------------------------------- /rt1015/rt1015.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {36580C07-EDC3-4C2B-B45F-6AB017E01A5D} 23 | {1bc93793-694f-48fe-9372-81e2b05556fd} 24 | v4.5 25 | 11.0 26 | Win8.1 Debug 27 | Win32 28 | rt1015 29 | 30 | 31 | 32 | Windows10 33 | true 34 | WindowsKernelModeDriver10.0 35 | Driver 36 | KMDF 37 | 38 | 39 | Windows10 40 | false 41 | WindowsKernelModeDriver10.0 42 | Driver 43 | KMDF 44 | 45 | 46 | Windows10 47 | true 48 | WindowsKernelModeDriver10.0 49 | Driver 50 | KMDF 51 | 52 | 53 | Windows10 54 | false 55 | WindowsKernelModeDriver10.0 56 | Driver 57 | KMDF 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | DbgengKernelDebugger 69 | 70 | 71 | DbgengKernelDebugger 72 | 73 | 74 | DbgengKernelDebugger 75 | 76 | 77 | DbgengKernelDebugger 78 | 79 | 80 | 81 | true 82 | trace.h 83 | true 84 | false 85 | 86 | 87 | 1.0.1 88 | 89 | 90 | 91 | 92 | true 93 | trace.h 94 | true 95 | false 96 | 97 | 98 | 1.0.1 99 | 100 | 101 | 102 | 103 | true 104 | trace.h 105 | true 106 | false 107 | 108 | 109 | 1.0.1 110 | 111 | 112 | 113 | 114 | true 115 | trace.h 116 | true 117 | false 118 | 119 | 120 | 1.0.1 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015/2017 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # Visual Studio 2017 auto generated files 34 | Generated\ Files/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # Benchmark Results 50 | BenchmarkDotNet.Artifacts/ 51 | 52 | # .NET Core 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_h.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *_wpftmp.csproj 81 | *.log 82 | *.vspscc 83 | *.vssscc 84 | .builds 85 | *.pidb 86 | *.svclog 87 | *.scc 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush personal settings 296 | .cr/personal 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | 333 | # Local History for Visual Studio 334 | .localhistory/ 335 | -------------------------------------------------------------------------------- /rt1015 Package/rt1015 Package.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {3DAE7ED3-003A-4495-8352-3D7B5B5D846F} 23 | {4605da2c-74a5-4865-98e1-152ef136825f} 24 | v4.5 25 | 11.0 26 | Win8.1 Debug 27 | Win32 28 | rt1015_Package 29 | $(LatestTargetPlatformVersion) 30 | 31 | 32 | 33 | Windows10 34 | true 35 | WindowsKernelModeDriver10.0 36 | Utility 37 | Package 38 | true 39 | 40 | 41 | Windows10 42 | false 43 | WindowsKernelModeDriver10.0 44 | Utility 45 | Package 46 | true 47 | 48 | 49 | Windows10 50 | true 51 | WindowsKernelModeDriver10.0 52 | Utility 53 | Package 54 | true 55 | 56 | 57 | Windows10 58 | false 59 | WindowsKernelModeDriver10.0 60 | Utility 61 | Package 62 | true 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | DbgengKernelDebugger 74 | False 75 | True 76 | 77 | 78 | 79 | False 80 | False 81 | True 82 | 83 | 133563 84 | 85 | 86 | DbgengKernelDebugger 87 | False 88 | True 89 | 90 | 91 | 92 | False 93 | False 94 | True 95 | 96 | 133563 97 | 98 | 99 | DbgengKernelDebugger 100 | False 101 | True 102 | 103 | 104 | 105 | False 106 | False 107 | True 108 | 109 | 133563 110 | 111 | 112 | DbgengKernelDebugger 113 | False 114 | True 115 | 116 | 117 | 118 | False 119 | False 120 | True 121 | 122 | 133563 123 | 124 | 125 | 126 | SHA256 127 | 128 | 129 | 130 | 131 | SHA256 132 | 133 | 134 | 135 | 136 | SHA256 137 | 138 | 139 | 140 | 141 | SHA256 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | {36580c07-edc3-4c2b-b45f-6ab017e01a5d} 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /rt1015/spb.c: -------------------------------------------------------------------------------- 1 | /*++ 2 | Copyright (c) Microsoft Corporation. All Rights Reserved. 3 | Sample code. Dealpoint ID #843729. 4 | 5 | Module Name: 6 | 7 | spb.c 8 | 9 | Abstract: 10 | 11 | Contains all I2C-specific functionality 12 | 13 | Environment: 14 | 15 | Kernel mode 16 | 17 | Revision History: 18 | 19 | --*/ 20 | 21 | #include "rt1015.h" 22 | #include "spb.h" 23 | #include 24 | 25 | static ULONG Rt1015DebugLevel = 100; 26 | static ULONG Rt1015DebugCatagories = DBG_INIT || DBG_PNP || DBG_IOCTL; 27 | 28 | NTSTATUS 29 | SpbDoWriteDataSynchronously( 30 | IN SPB_CONTEXT* SpbContext, 31 | IN PVOID Data, 32 | IN ULONG Length 33 | ) 34 | /*++ 35 | 36 | Routine Description: 37 | 38 | This helper routine abstracts creating and sending an I/O 39 | request (I2C Write) to the Spb I/O target. 40 | 41 | Arguments: 42 | 43 | SpbContext - Pointer to the current device context 44 | Address - The I2C register address to write to 45 | Data - A buffer to receive the data at at the above address 46 | Length - The amount of data to be read from the above address 47 | 48 | Return Value: 49 | 50 | NTSTATUS Status indicating success or failure 51 | 52 | --*/ 53 | { 54 | PUCHAR buffer; 55 | ULONG length; 56 | WDFMEMORY memory; 57 | WDF_MEMORY_DESCRIPTOR memoryDescriptor; 58 | NTSTATUS status; 59 | 60 | length = Length; 61 | memory = NULL; 62 | 63 | if (length > DEFAULT_SPB_BUFFER_SIZE) 64 | { 65 | status = WdfMemoryCreate( 66 | WDF_NO_OBJECT_ATTRIBUTES, 67 | NonPagedPool, 68 | RT1015_POOL_TAG, 69 | length, 70 | &memory, 71 | (PVOID*)&buffer); 72 | 73 | if (!NT_SUCCESS(status)) 74 | { 75 | Rt1015Print( 76 | DEBUG_LEVEL_ERROR, 77 | DBG_IOCTL, 78 | "Error allocating memory for Spb write - %!STATUS!", 79 | status); 80 | goto exit; 81 | } 82 | 83 | WDF_MEMORY_DESCRIPTOR_INIT_HANDLE( 84 | &memoryDescriptor, 85 | memory, 86 | NULL); 87 | } 88 | else 89 | { 90 | buffer = (PUCHAR)WdfMemoryGetBuffer(SpbContext->WriteMemory, NULL); 91 | 92 | WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( 93 | &memoryDescriptor, 94 | (PVOID)buffer, 95 | length); 96 | } 97 | 98 | RtlCopyMemory(buffer, Data, length); 99 | 100 | status = WdfIoTargetSendWriteSynchronously( 101 | SpbContext->SpbIoTarget, 102 | NULL, 103 | &memoryDescriptor, 104 | NULL, 105 | NULL, 106 | NULL); 107 | 108 | if (!NT_SUCCESS(status)) 109 | { 110 | Rt1015Print( 111 | DEBUG_LEVEL_ERROR, 112 | DBG_IOCTL, 113 | "Error writing to Spb - %!STATUS!", 114 | status); 115 | goto exit; 116 | } 117 | 118 | exit: 119 | 120 | if (NULL != memory) 121 | { 122 | WdfObjectDelete(memory); 123 | } 124 | 125 | return status; 126 | } 127 | 128 | NTSTATUS 129 | SpbWriteDataSynchronously( 130 | IN SPB_CONTEXT* SpbContext, 131 | IN PVOID Data, 132 | IN ULONG Length 133 | ) 134 | /*++ 135 | 136 | Routine Description: 137 | 138 | This routine abstracts creating and sending an I/O 139 | request (I2C Write) to the Spb I/O target and utilizes 140 | a helper routine to do work inside of locked code. 141 | 142 | Arguments: 143 | 144 | SpbContext - Pointer to the current device context 145 | Address - The I2C register address to write to 146 | Data - A buffer to receive the data at at the above address 147 | Length - The amount of data to be read from the above address 148 | 149 | Return Value: 150 | 151 | NTSTATUS Status indicating success or failure 152 | 153 | --*/ 154 | { 155 | NTSTATUS status; 156 | 157 | WdfWaitLockAcquire(SpbContext->SpbLock, NULL); 158 | 159 | status = SpbDoWriteDataSynchronously( 160 | SpbContext, 161 | Data, 162 | Length); 163 | 164 | WdfWaitLockRelease(SpbContext->SpbLock); 165 | 166 | return status; 167 | } 168 | 169 | NTSTATUS 170 | SpbXferDataSynchronously( 171 | _In_ SPB_CONTEXT* SpbContext, 172 | _In_ PVOID SendData, 173 | _In_ ULONG SendLength, 174 | _In_reads_bytes_(Length) PVOID Data, 175 | _In_ ULONG Length 176 | ) 177 | /*++ 178 | Routine Description: 179 | This helper routine abstracts creating and sending an I/O 180 | request (I2C Read) to the Spb I/O target. 181 | Arguments: 182 | SpbContext - Pointer to the current device context 183 | Address - The I2C register address to read from 184 | Data - A buffer to receive the data at at the above address 185 | Length - The amount of data to be read from the above address 186 | Return Value: 187 | NTSTATUS Status indicating success or failure 188 | --*/ 189 | { 190 | PUCHAR buffer; 191 | WDFMEMORY memory; 192 | WDF_MEMORY_DESCRIPTOR memoryDescriptor; 193 | NTSTATUS status; 194 | ULONG_PTR bytesRead; 195 | 196 | WdfWaitLockAcquire(SpbContext->SpbLock, NULL); 197 | 198 | memory = NULL; 199 | status = STATUS_INVALID_PARAMETER; 200 | bytesRead = 0; 201 | 202 | // 203 | // Xfer transactions start by writing an address pointer 204 | // 205 | status = SpbDoWriteDataSynchronously( 206 | SpbContext, 207 | SendData, 208 | SendLength); 209 | 210 | if (!NT_SUCCESS(status)) 211 | { 212 | Rt1015Print( 213 | DEBUG_LEVEL_ERROR, 214 | DBG_IOCTL, 215 | "Error setting address pointer for Spb read - %!STATUS!", 216 | status); 217 | goto exit; 218 | } 219 | 220 | if (Length > DEFAULT_SPB_BUFFER_SIZE) 221 | { 222 | status = WdfMemoryCreate( 223 | WDF_NO_OBJECT_ATTRIBUTES, 224 | NonPagedPool, 225 | RT1015_POOL_TAG, 226 | Length, 227 | &memory, 228 | (PVOID*)&buffer); 229 | 230 | if (!NT_SUCCESS(status)) 231 | { 232 | Rt1015Print( 233 | DEBUG_LEVEL_ERROR, 234 | DBG_IOCTL, 235 | "Error allocating memory for Spb read - %!STATUS!", 236 | status); 237 | goto exit; 238 | } 239 | 240 | WDF_MEMORY_DESCRIPTOR_INIT_HANDLE( 241 | &memoryDescriptor, 242 | memory, 243 | NULL); 244 | } 245 | else 246 | { 247 | buffer = (PUCHAR)WdfMemoryGetBuffer(SpbContext->ReadMemory, NULL); 248 | 249 | WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( 250 | &memoryDescriptor, 251 | (PVOID)buffer, 252 | Length); 253 | } 254 | 255 | 256 | status = WdfIoTargetSendReadSynchronously( 257 | SpbContext->SpbIoTarget, 258 | NULL, 259 | &memoryDescriptor, 260 | NULL, 261 | NULL, 262 | &bytesRead); 263 | 264 | if (!NT_SUCCESS(status) || 265 | bytesRead != Length) 266 | { 267 | Rt1015Print( 268 | DEBUG_LEVEL_ERROR, 269 | DBG_IOCTL, 270 | "Error reading from Spb - %!STATUS!", 271 | status); 272 | goto exit; 273 | } 274 | 275 | // 276 | // Copy back to the caller's buffer 277 | // 278 | RtlCopyMemory(Data, buffer, Length); 279 | 280 | exit: 281 | if (NULL != memory) 282 | { 283 | WdfObjectDelete(memory); 284 | } 285 | 286 | WdfWaitLockRelease(SpbContext->SpbLock); 287 | 288 | return status; 289 | } 290 | 291 | VOID 292 | SpbTargetDeinitialize( 293 | IN WDFDEVICE FxDevice, 294 | IN SPB_CONTEXT* SpbContext 295 | ) 296 | /*++ 297 | 298 | Routine Description: 299 | 300 | This helper routine is used to free any members added to the SPB_CONTEXT, 301 | note the SPB I/O target is parented to the device and will be 302 | closed and free'd when the device is removed. 303 | 304 | Arguments: 305 | 306 | FxDevice - Handle to the framework device object 307 | SpbContext - Pointer to the current device context 308 | 309 | Return Value: 310 | 311 | NTSTATUS Status indicating success or failure 312 | 313 | --*/ 314 | { 315 | UNREFERENCED_PARAMETER(FxDevice); 316 | UNREFERENCED_PARAMETER(SpbContext); 317 | 318 | // 319 | // Free any SPB_CONTEXT allocations here 320 | // 321 | if (SpbContext->SpbLock != NULL) 322 | { 323 | WdfObjectDelete(SpbContext->SpbLock); 324 | } 325 | 326 | if (SpbContext->ReadMemory != NULL) 327 | { 328 | WdfObjectDelete(SpbContext->ReadMemory); 329 | } 330 | 331 | if (SpbContext->WriteMemory != NULL) 332 | { 333 | WdfObjectDelete(SpbContext->WriteMemory); 334 | } 335 | } 336 | 337 | NTSTATUS 338 | SpbTargetInitialize( 339 | IN WDFDEVICE FxDevice, 340 | IN SPB_CONTEXT* SpbContext 341 | ) 342 | /*++ 343 | 344 | Routine Description: 345 | 346 | This helper routine opens the Spb I/O target and 347 | initializes a request object used for the lifetime 348 | of communication between this driver and Spb. 349 | 350 | Arguments: 351 | 352 | FxDevice - Handle to the framework device object 353 | SpbContext - Pointer to the current device context 354 | 355 | Return Value: 356 | 357 | NTSTATUS Status indicating success or failure 358 | 359 | --*/ 360 | { 361 | WDF_OBJECT_ATTRIBUTES objectAttributes; 362 | WDF_IO_TARGET_OPEN_PARAMS openParams; 363 | UNICODE_STRING spbDeviceName; 364 | WCHAR spbDeviceNameBuffer[RESOURCE_HUB_PATH_SIZE]; 365 | NTSTATUS status; 366 | 367 | WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes); 368 | objectAttributes.ParentObject = FxDevice; 369 | 370 | status = WdfIoTargetCreate( 371 | FxDevice, 372 | &objectAttributes, 373 | &SpbContext->SpbIoTarget); 374 | 375 | if (!NT_SUCCESS(status)) 376 | { 377 | Rt1015Print( 378 | DEBUG_LEVEL_ERROR, 379 | DBG_IOCTL, 380 | "Error creating IoTarget object - %!STATUS!", 381 | status); 382 | 383 | WdfObjectDelete(SpbContext->SpbIoTarget); 384 | goto exit; 385 | } 386 | 387 | RtlInitEmptyUnicodeString( 388 | &spbDeviceName, 389 | spbDeviceNameBuffer, 390 | sizeof(spbDeviceNameBuffer)); 391 | 392 | status = RESOURCE_HUB_CREATE_PATH_FROM_ID( 393 | &spbDeviceName, 394 | SpbContext->I2cResHubId.LowPart, 395 | SpbContext->I2cResHubId.HighPart); 396 | 397 | if (!NT_SUCCESS(status)) 398 | { 399 | Rt1015Print( 400 | DEBUG_LEVEL_ERROR, 401 | DBG_IOCTL, 402 | "Error creating Spb resource hub path string - %!STATUS!", 403 | status); 404 | goto exit; 405 | } 406 | 407 | WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME( 408 | &openParams, 409 | &spbDeviceName, 410 | (GENERIC_READ | GENERIC_WRITE)); 411 | 412 | openParams.ShareAccess = 0; 413 | openParams.CreateDisposition = FILE_OPEN; 414 | openParams.FileAttributes = FILE_ATTRIBUTE_NORMAL; 415 | 416 | status = WdfIoTargetOpen(SpbContext->SpbIoTarget, &openParams); 417 | 418 | if (!NT_SUCCESS(status)) 419 | { 420 | Rt1015Print( 421 | DEBUG_LEVEL_ERROR, 422 | DBG_IOCTL, 423 | "Error opening Spb target for communication - %!STATUS!", 424 | status); 425 | goto exit; 426 | } 427 | 428 | // 429 | // Allocate some fixed-size buffers from NonPagedPool for typical 430 | // Spb transaction sizes to avoid pool fragmentation in most cases 431 | // 432 | status = WdfMemoryCreate( 433 | WDF_NO_OBJECT_ATTRIBUTES, 434 | NonPagedPool, 435 | RT1015_POOL_TAG, 436 | DEFAULT_SPB_BUFFER_SIZE, 437 | &SpbContext->WriteMemory, 438 | NULL); 439 | 440 | if (!NT_SUCCESS(status)) 441 | { 442 | Rt1015Print( 443 | DEBUG_LEVEL_ERROR, 444 | DBG_IOCTL, 445 | "Error allocating default memory for Spb write - %!STATUS!", 446 | status); 447 | goto exit; 448 | } 449 | 450 | status = WdfMemoryCreate( 451 | WDF_NO_OBJECT_ATTRIBUTES, 452 | NonPagedPool, 453 | RT1015_POOL_TAG, 454 | DEFAULT_SPB_BUFFER_SIZE, 455 | &SpbContext->ReadMemory, 456 | NULL); 457 | 458 | if (!NT_SUCCESS(status)) 459 | { 460 | Rt1015Print( 461 | DEBUG_LEVEL_ERROR, 462 | DBG_IOCTL, 463 | "Error allocating default memory for Spb read - %!STATUS!", 464 | status); 465 | goto exit; 466 | } 467 | 468 | // 469 | // Allocate a waitlock to guard access to the default buffers 470 | // 471 | status = WdfWaitLockCreate( 472 | WDF_NO_OBJECT_ATTRIBUTES, 473 | &SpbContext->SpbLock); 474 | 475 | if (!NT_SUCCESS(status)) 476 | { 477 | Rt1015Print( 478 | DEBUG_LEVEL_ERROR, 479 | DBG_IOCTL, 480 | "Error creating Spb Waitlock - %!STATUS!", 481 | status); 482 | goto exit; 483 | } 484 | 485 | exit: 486 | 487 | if (!NT_SUCCESS(status)) 488 | { 489 | SpbTargetDeinitialize(FxDevice, SpbContext); 490 | } 491 | 492 | return status; 493 | } -------------------------------------------------------------------------------- /rt1015/registers.h: -------------------------------------------------------------------------------- 1 | #ifndef __RT1015_H__ 2 | #define __RT1015_H__ 3 | 4 | #define RT1015_DEVICE_ID_VAL 0x1011 5 | #define RT1015_DEVICE_ID_VAL2 0x1015 6 | 7 | #define RT1015_RESET 0x0000 8 | #define RT1015_CLK2 0x0004 9 | #define RT1015_CLK3 0x0006 10 | #define RT1015_PLL1 0x000a 11 | #define RT1015_PLL2 0x000c 12 | #define RT1015_DUM_RW1 0x000e 13 | #define RT1015_DUM_RW2 0x0010 14 | #define RT1015_DUM_RW3 0x0012 15 | #define RT1015_DUM_RW4 0x0014 16 | #define RT1015_DUM_RW5 0x0016 17 | #define RT1015_DUM_RW6 0x0018 18 | #define RT1015_CLK_DET 0x0020 19 | #define RT1015_SIL_DET 0x0022 20 | #define RT1015_CUSTOMER_ID 0x0076 21 | #define RT1015_PCODE_FWVER 0x0078 22 | #define RT1015_VER_ID 0x007a 23 | #define RT1015_VENDOR_ID 0x007c 24 | #define RT1015_DEVICE_ID 0x007d 25 | #define RT1015_PAD_DRV1 0x00f0 26 | #define RT1015_PAD_DRV2 0x00f2 27 | #define RT1015_GAT_BOOST 0x00f3 28 | #define RT1015_PRO_ALT 0x00f4 29 | #define RT1015_OSCK_STA 0x00f6 30 | #define RT1015_MAN_I2C 0x0100 31 | #define RT1015_DAC1 0x0102 32 | #define RT1015_DAC2 0x0104 33 | #define RT1015_DAC3 0x0106 34 | #define RT1015_ADC1 0x010c 35 | #define RT1015_ADC2 0x010e 36 | #define RT1015_TDM_MASTER 0x0111 37 | #define RT1015_TDM_TCON 0x0112 38 | #define RT1015_TDM1_1 0x0114 39 | #define RT1015_TDM1_2 0x0116 40 | #define RT1015_TDM1_3 0x0118 41 | #define RT1015_TDM1_4 0x011a 42 | #define RT1015_TDM1_5 0x011c 43 | #define RT1015_MIXER1 0x0300 44 | #define RT1015_MIXER2 0x0302 45 | #define RT1015_ANA_PROTECT1 0x0311 46 | #define RT1015_ANA_CTRL_SEQ1 0x0313 47 | #define RT1015_ANA_CTRL_SEQ2 0x0314 48 | #define RT1015_VBAT_DET_DEB 0x031a 49 | #define RT1015_VBAT_VOLT_DET1 0x031c 50 | #define RT1015_VBAT_VOLT_DET2 0x031d 51 | #define RT1015_VBAT_TEST_OUT1 0x031e 52 | #define RT1015_VBAT_TEST_OUT2 0x031f 53 | #define RT1015_VBAT_PROT_ATT 0x0320 54 | #define RT1015_VBAT_DET_CODE 0x0321 55 | #define RT1015_PWR1 0x0322 56 | #define RT1015_PWR4 0x0328 57 | #define RT1015_PWR5 0x0329 58 | #define RT1015_PWR6 0x032a 59 | #define RT1015_PWR7 0x032b 60 | #define RT1015_PWR8 0x032c 61 | #define RT1015_PWR9 0x032d 62 | #define RT1015_CLASSD_SEQ 0x032e 63 | #define RT1015_SMART_BST_CTRL1 0x0330 64 | #define RT1015_SMART_BST_CTRL2 0x0332 65 | #define RT1015_ANA_CTRL1 0x0334 66 | #define RT1015_ANA_CTRL2 0x0336 67 | #define RT1015_PWR_STATE_CTRL 0x0338 68 | #define RT1015_MONO_DYNA_CTRL 0x04fa 69 | #define RT1015_MONO_DYNA_CTRL1 0x04fc 70 | #define RT1015_MONO_DYNA_CTRL2 0x04fe 71 | #define RT1015_MONO_DYNA_CTRL3 0x0500 72 | #define RT1015_MONO_DYNA_CTRL4 0x0502 73 | #define RT1015_MONO_DYNA_CTRL5 0x0504 74 | #define RT1015_SPK_VOL 0x0506 75 | #define RT1015_SHORT_DETTOP1 0x0508 76 | #define RT1015_SHORT_DETTOP2 0x050a 77 | #define RT1015_SPK_DC_DETECT1 0x0519 78 | #define RT1015_SPK_DC_DETECT2 0x051a 79 | #define RT1015_SPK_DC_DETECT3 0x051b 80 | #define RT1015_SPK_DC_DETECT4 0x051d 81 | #define RT1015_SPK_DC_DETECT5 0x051f 82 | #define RT1015_BAT_RPO_STEP1 0x0536 83 | #define RT1015_BAT_RPO_STEP2 0x0538 84 | #define RT1015_BAT_RPO_STEP3 0x053a 85 | #define RT1015_BAT_RPO_STEP4 0x053c 86 | #define RT1015_BAT_RPO_STEP5 0x053d 87 | #define RT1015_BAT_RPO_STEP6 0x053e 88 | #define RT1015_BAT_RPO_STEP7 0x053f 89 | #define RT1015_BAT_RPO_STEP8 0x0540 90 | #define RT1015_BAT_RPO_STEP9 0x0541 91 | #define RT1015_BAT_RPO_STEP10 0x0542 92 | #define RT1015_BAT_RPO_STEP11 0x0543 93 | #define RT1015_BAT_RPO_STEP12 0x0544 94 | #define RT1015_SPREAD_SPEC1 0x0568 95 | #define RT1015_SPREAD_SPEC2 0x056a 96 | #define RT1015_PAD_STATUS 0x1000 97 | #define RT1015_PADS_PULLING_CTRL1 0x1002 98 | #define RT1015_PADS_DRIVING 0x1006 99 | #define RT1015_SYS_RST1 0x1007 100 | #define RT1015_SYS_RST2 0x1009 101 | #define RT1015_SYS_GATING1 0x100a 102 | #define RT1015_TEST_MODE1 0x100c 103 | #define RT1015_TEST_MODE2 0x100d 104 | #define RT1015_TIMING_CTRL1 0x100e 105 | #define RT1015_PLL_INT 0x1010 106 | #define RT1015_TEST_OUT1 0x1020 107 | #define RT1015_DC_CALIB_CLSD1 0x1200 108 | #define RT1015_DC_CALIB_CLSD2 0x1202 109 | #define RT1015_DC_CALIB_CLSD3 0x1204 110 | #define RT1015_DC_CALIB_CLSD4 0x1206 111 | #define RT1015_DC_CALIB_CLSD5 0x1208 112 | #define RT1015_DC_CALIB_CLSD6 0x120a 113 | #define RT1015_DC_CALIB_CLSD7 0x120c 114 | #define RT1015_DC_CALIB_CLSD8 0x120e 115 | #define RT1015_DC_CALIB_CLSD9 0x1210 116 | #define RT1015_DC_CALIB_CLSD10 0x1212 117 | #define RT1015_CLSD_INTERNAL1 0x1300 118 | #define RT1015_CLSD_INTERNAL2 0x1302 119 | #define RT1015_CLSD_INTERNAL3 0x1304 120 | #define RT1015_CLSD_INTERNAL4 0x1305 121 | #define RT1015_CLSD_INTERNAL5 0x1306 122 | #define RT1015_CLSD_INTERNAL6 0x1308 123 | #define RT1015_CLSD_INTERNAL7 0x130a 124 | #define RT1015_CLSD_INTERNAL8 0x130c 125 | #define RT1015_CLSD_INTERNAL9 0x130e 126 | #define RT1015_CLSD_OCP_CTRL 0x130f 127 | #define RT1015_VREF_LV 0x1310 128 | #define RT1015_MBIAS1 0x1312 129 | #define RT1015_MBIAS2 0x1314 130 | #define RT1015_MBIAS3 0x1316 131 | #define RT1015_MBIAS4 0x1318 132 | #define RT1015_VREF_LV1 0x131a 133 | #define RT1015_S_BST_TIMING_INTER1 0x1322 134 | #define RT1015_S_BST_TIMING_INTER2 0x1323 135 | #define RT1015_S_BST_TIMING_INTER3 0x1324 136 | #define RT1015_S_BST_TIMING_INTER4 0x1325 137 | #define RT1015_S_BST_TIMING_INTER5 0x1326 138 | #define RT1015_S_BST_TIMING_INTER6 0x1327 139 | #define RT1015_S_BST_TIMING_INTER7 0x1328 140 | #define RT1015_S_BST_TIMING_INTER8 0x1329 141 | #define RT1015_S_BST_TIMING_INTER9 0x132a 142 | #define RT1015_S_BST_TIMING_INTER10 0x132b 143 | #define RT1015_S_BST_TIMING_INTER11 0x1330 144 | #define RT1015_S_BST_TIMING_INTER12 0x1331 145 | #define RT1015_S_BST_TIMING_INTER13 0x1332 146 | #define RT1015_S_BST_TIMING_INTER14 0x1333 147 | #define RT1015_S_BST_TIMING_INTER15 0x1334 148 | #define RT1015_S_BST_TIMING_INTER16 0x1335 149 | #define RT1015_S_BST_TIMING_INTER17 0x1336 150 | #define RT1015_S_BST_TIMING_INTER18 0x1337 151 | #define RT1015_S_BST_TIMING_INTER19 0x1338 152 | #define RT1015_S_BST_TIMING_INTER20 0x1339 153 | #define RT1015_S_BST_TIMING_INTER21 0x133a 154 | #define RT1015_S_BST_TIMING_INTER22 0x133b 155 | #define RT1015_S_BST_TIMING_INTER23 0x133c 156 | #define RT1015_S_BST_TIMING_INTER24 0x133d 157 | #define RT1015_S_BST_TIMING_INTER25 0x133e 158 | #define RT1015_S_BST_TIMING_INTER26 0x133f 159 | #define RT1015_S_BST_TIMING_INTER27 0x1340 160 | #define RT1015_S_BST_TIMING_INTER28 0x1341 161 | #define RT1015_S_BST_TIMING_INTER29 0x1342 162 | #define RT1015_S_BST_TIMING_INTER30 0x1343 163 | #define RT1015_S_BST_TIMING_INTER31 0x1344 164 | #define RT1015_S_BST_TIMING_INTER32 0x1345 165 | #define RT1015_S_BST_TIMING_INTER33 0x1346 166 | #define RT1015_S_BST_TIMING_INTER34 0x1347 167 | #define RT1015_S_BST_TIMING_INTER35 0x1348 168 | #define RT1015_S_BST_TIMING_INTER36 0x1349 169 | 170 | /* 0x0004 */ 171 | #define RT1015_CLK_SYS_PRE_SEL_MASK (0x3 << 14) 172 | #define RT1015_CLK_SYS_PRE_SEL_SFT 14 173 | #define RT1015_CLK_SYS_PRE_SEL_MCLK (0x0 << 14) 174 | #define RT1015_CLK_SYS_PRE_SEL_PLL (0x2 << 14) 175 | #define RT1015_PLL_SEL_MASK (0x1 << 13) 176 | #define RT1015_PLL_SEL_SFT 13 177 | #define RT1015_PLL_SEL_PLL_SRC2 (0x0 << 13) 178 | #define RT1015_PLL_SEL_BCLK (0x1 << 13) 179 | #define RT1015_FS_PD_MASK (0x7 << 4) 180 | #define RT1015_FS_PD_SFT 4 181 | 182 | /* 0x000a */ 183 | #define RT1015_PLL_M_MAX 0xf 184 | #define RT1015_PLL_M_MASK (RT1015_PLL_M_MAX << 12) 185 | #define RT1015_PLL_M_SFT 12 186 | #define RT1015_PLL_M_BP (0x1 << 11) 187 | #define RT1015_PLL_M_BP_SFT 11 188 | #define RT1015_PLL_N_MAX 0x1ff 189 | #define RT1015_PLL_N_MASK (RT1015_PLL_N_MAX << 0) 190 | #define RT1015_PLL_N_SFT 0 191 | 192 | /* 0x000c */ 193 | #define RT1015_PLL_BPK_MASK (0x1 << 5) 194 | #define RT1015_PLL_BPK (0x0 << 5) 195 | #define RT1015_PLL_K_MAX 0x1f 196 | #define RT1015_PLL_K_MASK (RT1015_PLL_K_MAX) 197 | #define RT1015_PLL_K_SFT 0 198 | 199 | /* 0x0020 */ 200 | #define RT1015_EN_BCLK_DET_MASK (0x1 << 15) 201 | #define RT1015_EN_BCLK_DET (0x1 << 15) 202 | #define RT1015_DIS_BCLK_DET (0x0 << 15) 203 | 204 | /* 0x007a */ 205 | #define RT1015_ID_MASK 0xff 206 | #define RT1015_ID_VERA 0x0 207 | #define RT1015_ID_VERB 0x1 208 | 209 | /* 0x00f2 */ 210 | #define RT1015_MONO_LR_SEL_MASK (0x3 << 4) 211 | #define RT1015_MONO_L_CHANNEL (0x0 << 4) 212 | #define RT1015_MONO_R_CHANNEL (0x1 << 4) 213 | #define RT1015_MONO_LR_MIX_CHANNEL (0x2 << 4) 214 | 215 | /* 0x0102 */ 216 | #define RT1015_DAC_VOL_MASK (0x7f << 9) 217 | #define RT1015_DAC_VOL_SFT 9 218 | 219 | /* 0x0104 */ 220 | #define RT1015_DAC_CLK (0x1 << 13) 221 | #define RT1015_DAC_CLK_BIT 13 222 | 223 | /* 0x0106 */ 224 | #define RT1015_DAC_MUTE_MASK (0x1 << 15) 225 | #define RT1015_DA_MUTE_SFT 15 226 | #define RT1015_DVOL_MUTE_FLAG_SFT 12 227 | 228 | /* 0x0111 */ 229 | #define RT1015_TCON_TDM_MS_MASK (0x1 << 14) 230 | #define RT1015_TCON_TDM_MS_SFT 14 231 | #define RT1015_TCON_TDM_MS_S (0x0 << 14) 232 | #define RT1015_TCON_TDM_MS_M (0x1 << 14) 233 | #define RT1015_I2S_DL_MASK (0x7 << 8) 234 | #define RT1015_I2S_DL_SFT 8 235 | #define RT1015_I2S_DL_16 (0x0 << 8) 236 | #define RT1015_I2S_DL_20 (0x1 << 8) 237 | #define RT1015_I2S_DL_24 (0x2 << 8) 238 | #define RT1015_I2S_DL_8 (0x3 << 8) 239 | #define RT1015_I2S_M_DF_MASK (0x7 << 0) 240 | #define RT1015_I2S_M_DF_SFT 0 241 | #define RT1015_I2S_M_DF_I2S (0x0) 242 | #define RT1015_I2S_M_DF_LEFT (0x1) 243 | #define RT1015_I2S_M_DF_PCM_A (0x2) 244 | #define RT1015_I2S_M_DF_PCM_B (0x3) 245 | #define RT1015_I2S_M_DF_PCM_A_N (0x6) 246 | #define RT1015_I2S_M_DF_PCM_B_N (0x7) 247 | 248 | /* TDM_tcon Setting (0x0112) */ 249 | #define RT1015_I2S_TCON_DF_MASK (0x7 << 13) 250 | #define RT1015_I2S_TCON_DF_SFT 13 251 | #define RT1015_I2S_TCON_DF_I2S (0x0 << 13) 252 | #define RT1015_I2S_TCON_DF_LEFT (0x1 << 13) 253 | #define RT1015_I2S_TCON_DF_PCM_A (0x2 << 13) 254 | #define RT1015_I2S_TCON_DF_PCM_B (0x3 << 13) 255 | #define RT1015_I2S_TCON_DF_PCM_A_N (0x6 << 13) 256 | #define RT1015_I2S_TCON_DF_PCM_B_N (0x7 << 13) 257 | #define RT1015_TCON_BCLK_SEL_MASK (0x3 << 10) 258 | #define RT1015_TCON_BCLK_SEL_SFT 10 259 | #define RT1015_TCON_BCLK_SEL_32FS (0x0 << 10) 260 | #define RT1015_TCON_BCLK_SEL_64FS (0x1 << 10) 261 | #define RT1015_TCON_BCLK_SEL_128FS (0x2 << 10) 262 | #define RT1015_TCON_BCLK_SEL_256FS (0x3 << 10) 263 | #define RT1015_TCON_CH_LEN_MASK (0x3 << 5) 264 | #define RT1015_TCON_CH_LEN_SFT 5 265 | #define RT1015_TCON_CH_LEN_16B (0x0 << 5) 266 | #define RT1015_TCON_CH_LEN_20B (0x1 << 5) 267 | #define RT1015_TCON_CH_LEN_24B (0x2 << 5) 268 | #define RT1015_TCON_CH_LEN_32B (0x3 << 5) 269 | #define RT1015_TCON_BCLK_MST_MASK (0x1 << 4) 270 | #define RT1015_TCON_BCLK_MST_SFT 4 271 | #define RT1015_TCON_BCLK_MST_INV (0x1 << 4) 272 | 273 | /* TDM1 Setting-1 (0x0114) */ 274 | #define RT1015_TDM_INV_BCLK_MASK (0x1 << 15) 275 | #define RT1015_TDM_INV_BCLK_SFT 15 276 | #define RT1015_TDM_INV_BCLK (0x1 << 15) 277 | #define RT1015_I2S_CH_TX_MASK (0x3 << 10) 278 | #define RT1015_I2S_CH_TX_SFT 10 279 | #define RT1015_I2S_TX_2CH (0x0 << 10) 280 | #define RT1015_I2S_TX_4CH (0x1 << 10) 281 | #define RT1015_I2S_TX_6CH (0x2 << 10) 282 | #define RT1015_I2S_TX_8CH (0x3 << 10) 283 | #define RT1015_I2S_CH_RX_MASK (0x3 << 8) 284 | #define RT1015_I2S_CH_RX_SFT 8 285 | #define RT1015_I2S_RX_2CH (0x0 << 8) 286 | #define RT1015_I2S_RX_4CH (0x1 << 8) 287 | #define RT1015_I2S_RX_6CH (0x2 << 8) 288 | #define RT1015_I2S_RX_8CH (0x3 << 8) 289 | #define RT1015_I2S_LR_CH_SEL_MASK (0x1 << 7) 290 | #define RT1015_I2S_LR_CH_SEL_SFT 7 291 | #define RT1015_I2S_LEFT_CH_SEL (0x0 << 7) 292 | #define RT1015_I2S_RIGHT_CH_SEL (0x1 << 7) 293 | #define RT1015_I2S_CH_TX_LEN_MASK (0x7 << 4) 294 | #define RT1015_I2S_CH_TX_LEN_SFT 4 295 | #define RT1015_I2S_CH_TX_LEN_16B (0x0 << 4) 296 | #define RT1015_I2S_CH_TX_LEN_20B (0x1 << 4) 297 | #define RT1015_I2S_CH_TX_LEN_24B (0x2 << 4) 298 | #define RT1015_I2S_CH_TX_LEN_32B (0x3 << 4) 299 | #define RT1015_I2S_CH_TX_LEN_8B (0x4 << 4) 300 | #define RT1015_I2S_CH_RX_LEN_MASK (0x7 << 0) 301 | #define RT1015_I2S_CH_RX_LEN_SFT 0 302 | #define RT1015_I2S_CH_RX_LEN_16B (0x0 << 0) 303 | #define RT1015_I2S_CH_RX_LEN_20B (0x1 << 0) 304 | #define RT1015_I2S_CH_RX_LEN_24B (0x2 << 0) 305 | #define RT1015_I2S_CH_RX_LEN_32B (0x3 << 0) 306 | #define RT1015_I2S_CH_RX_LEN_8B (0x4 << 0) 307 | 308 | /* TDM1 Setting-4 (0x011a) */ 309 | #define RT1015_TDM_I2S_TX_L_DAC1_1_MASK (0x7 << 12) 310 | #define RT1015_TDM_I2S_TX_R_DAC1_1_MASK (0x7 << 8) 311 | #define RT1015_TDM_I2S_TX_L_DAC1_1_SFT 12 312 | #define RT1015_TDM_I2S_TX_R_DAC1_1_SFT 8 313 | 314 | /* 0x0330 */ 315 | #define RT1015_ABST_AUTO_EN_MASK (0x1 << 13) 316 | #define RT1015_ABST_AUTO_MODE (0x1 << 13) 317 | #define RT1015_ABST_REG_MODE (0x0 << 13) 318 | #define RT1015_ABST_FIX_TGT_MASK (0x1 << 12) 319 | #define RT1015_ABST_FIX_TGT_EN (0x1 << 12) 320 | #define RT1015_ABST_FIX_TGT_DIS (0x0 << 12) 321 | #define RT1015_BYPASS_SWR_REG_MASK (0x1 << 7) 322 | #define RT1015_BYPASS_SWRREG_BYPASS (0x1 << 7) 323 | #define RT1015_BYPASS_SWRREG_PASS (0x0 << 7) 324 | 325 | /* 0x0322 */ 326 | #define RT1015_PWR_LDO2 (0x1 << 15) 327 | #define RT1015_PWR_LDO2_BIT 15 328 | #define RT1015_PWR_DAC (0x1 << 14) 329 | #define RT1015_PWR_DAC_BIT 14 330 | #define RT1015_PWR_INTCLK (0x1 << 13) 331 | #define RT1015_PWR_INTCLK_BIT 13 332 | #define RT1015_PWR_ISENSE (0x1 << 12) 333 | #define RT1015_PWR_ISENSE_BIT 12 334 | #define RT1015_PWR_VSENSE (0x1 << 10) 335 | #define RT1015_PWR_VSENSE_BIT 10 336 | #define RT1015_PWR_PLL (0x1 << 9) 337 | #define RT1015_PWR_PLL_BIT 9 338 | #define RT1015_PWR_BG_1_2 (0x1 << 8) 339 | #define RT1015_PWR_BG_1_2_BIT 8 340 | #define RT1015_PWR_MBIAS_BG (0x1 << 7) 341 | #define RT1015_PWR_MBIAS_BG_BIT 7 342 | #define RT1015_PWR_VBAT (0x1 << 6) 343 | #define RT1015_PWR_VBAT_BIT 6 344 | #define RT1015_PWR_MBIAS (0x1 << 4) 345 | #define RT1015_PWR_MBIAS_BIT 4 346 | #define RT1015_PWR_ADCV (0x1 << 3) 347 | #define RT1015_PWR_ADCV_BIT 3 348 | #define RT1015_PWR_MIXERV (0x1 << 2) 349 | #define RT1015_PWR_MIXERV_BIT 2 350 | #define RT1015_PWR_SUMV (0x1 << 1) 351 | #define RT1015_PWR_SUMV_BIT 1 352 | #define RT1015_PWR_VREFLV (0x1 << 0) 353 | #define RT1015_PWR_VREFLV_BIT 0 354 | 355 | /* 0x0324 */ 356 | #define RT1015_PWR_BASIC (0x1 << 15) 357 | #define RT1015_PWR_BASIC_BIT 15 358 | #define RT1015_PWR_SD (0x1 << 14) 359 | #define RT1015_PWR_SD_BIT 14 360 | #define RT1015_PWR_IBIAS (0x1 << 13) 361 | #define RT1015_PWR_IBIAS_BIT 13 362 | #define RT1015_PWR_VCM (0x1 << 11) 363 | #define RT1015_PWR_VCM_BIT 11 364 | 365 | /* 0x0328 */ 366 | #define RT1015_PWR_SWR (0x1 << 12) 367 | #define RT1015_PWR_SWR_BIT 12 368 | 369 | /* 0x0519 */ 370 | #define RT1015_EN_CLA_D_DC_DET_MASK (0x1 << 12) 371 | #define RT1015_EN_CLA_D_DC_DET (0x1 << 12) 372 | #define RT1015_DIS_CLA_D_DC_DET (0x0 << 12) 373 | 374 | /* 0x1300 */ 375 | #define RT1015_PWR_CLSD (0x1 << 12) 376 | #define RT1015_PWR_CLSD_BIT 12 377 | 378 | /* 0x007a */ 379 | #define RT1015_ID_MASK 0xff 380 | #define RT1015_ID_VERA 0x0 381 | #define RT1015_ID_VERB 0x1 382 | 383 | /* System Clock Source */ 384 | enum { 385 | RT1015_SCLK_S_MCLK, 386 | RT1015_SCLK_S_PLL, 387 | }; 388 | 389 | /* PLL1 Source */ 390 | enum { 391 | RT1015_PLL_S_MCLK, 392 | RT1015_PLL_S_BCLK, 393 | }; 394 | 395 | enum { 396 | RT1015_AIF1, 397 | RT1015_AIFS, 398 | }; 399 | 400 | enum { 401 | RT1015_VERA, 402 | RT1015_VERB, 403 | }; 404 | 405 | enum { 406 | BYPASS, 407 | ADAPTIVE, 408 | FIXED_ADAPTIVE, 409 | }; 410 | 411 | enum { 412 | RT1015_Enable_Boost = 0, 413 | RT1015_Bypass_Boost, 414 | }; 415 | 416 | enum { 417 | RT1015_HW_28 = 0, 418 | RT1015_HW_29, 419 | }; 420 | 421 | #endif /* __RT1015_H__ */ -------------------------------------------------------------------------------- /rt1015/rt1015.c: -------------------------------------------------------------------------------- 1 | #include "rt1015.h" 2 | #include "registers.h" 3 | 4 | #define bool int 5 | 6 | static ULONG Rt1015DebugLevel = 100; 7 | static ULONG Rt1015DebugCatagories = DBG_INIT || DBG_PNP || DBG_IOCTL; 8 | 9 | NTSTATUS 10 | DriverEntry( 11 | __in PDRIVER_OBJECT DriverObject, 12 | __in PUNICODE_STRING RegistryPath 13 | ) 14 | { 15 | NTSTATUS status = STATUS_SUCCESS; 16 | WDF_DRIVER_CONFIG config; 17 | WDF_OBJECT_ATTRIBUTES attributes; 18 | 19 | Rt1015Print(DEBUG_LEVEL_INFO, DBG_INIT, 20 | "Driver Entry\n"); 21 | 22 | WDF_DRIVER_CONFIG_INIT(&config, Rt1015EvtDeviceAdd); 23 | 24 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 25 | 26 | // 27 | // Create a framework driver object to represent our driver. 28 | // 29 | 30 | status = WdfDriverCreate(DriverObject, 31 | RegistryPath, 32 | &attributes, 33 | &config, 34 | WDF_NO_HANDLE 35 | ); 36 | 37 | if (!NT_SUCCESS(status)) 38 | { 39 | Rt1015Print(DEBUG_LEVEL_ERROR, DBG_INIT, 40 | "WdfDriverCreate failed with status 0x%x\n", status); 41 | } 42 | 43 | return status; 44 | } 45 | 46 | static NTSTATUS rt1015_reg_write(PRT1015_CONTEXT pDevice, uint16_t reg, uint16_t data) 47 | { 48 | uint16_t rawdata[2]; 49 | rawdata[0] = RtlUshortByteSwap(reg); 50 | rawdata[1] = RtlUshortByteSwap(data); 51 | return SpbWriteDataSynchronously(&pDevice->I2CContext, rawdata, sizeof(rawdata)); 52 | } 53 | 54 | struct reg { 55 | UINT16 reg; 56 | UINT16 val; 57 | }; 58 | 59 | static NTSTATUS rt1015_reg_read(PRT1015_CONTEXT pDevice, uint16_t reg, uint16_t* data) 60 | { 61 | uint16_t reg_swap = RtlUshortByteSwap(reg); 62 | uint16_t data_swap = 0; 63 | NTSTATUS ret = SpbXferDataSynchronously(&pDevice->I2CContext, ®_swap, sizeof(uint16_t), &data_swap, sizeof(uint16_t)); 64 | *data = RtlUshortByteSwap(data_swap); 65 | return ret; 66 | } 67 | 68 | static NTSTATUS rt1015_reg_burstWrite(PRT1015_CONTEXT pDevice, struct reg* regs, int regCount) { 69 | NTSTATUS status = STATUS_NO_MEMORY; 70 | for (int i = 0; i < regCount; i++) { 71 | struct reg* regToSet = ®s[i]; 72 | status = rt1015_reg_write(pDevice, regToSet->reg, regToSet->val); 73 | if (!NT_SUCCESS(status)) { 74 | return status; 75 | } 76 | } 77 | return status; 78 | } 79 | 80 | NTSTATUS 81 | GetDeviceUID( 82 | _In_ WDFDEVICE FxDevice, 83 | _In_ PINT32 PUID 84 | ) 85 | { 86 | NTSTATUS status = STATUS_ACPI_NOT_INITIALIZED; 87 | ACPI_EVAL_INPUT_BUFFER_EX inputBuffer; 88 | RtlZeroMemory(&inputBuffer, sizeof(inputBuffer)); 89 | 90 | inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE_EX; 91 | status = RtlStringCchPrintfA( 92 | inputBuffer.MethodName, 93 | sizeof(inputBuffer.MethodName), 94 | "_UID" 95 | ); 96 | if (!NT_SUCCESS(status)) { 97 | return status; 98 | } 99 | 100 | WDFMEMORY outputMemory; 101 | PACPI_EVAL_OUTPUT_BUFFER outputBuffer; 102 | size_t outputArgumentBufferSize = 32; 103 | size_t outputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + outputArgumentBufferSize; 104 | 105 | WDF_OBJECT_ATTRIBUTES attributes; 106 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 107 | attributes.ParentObject = FxDevice; 108 | 109 | status = WdfMemoryCreate(&attributes, 110 | NonPagedPoolNx, 111 | 0, 112 | outputBufferSize, 113 | &outputMemory, 114 | (PVOID*)&outputBuffer); 115 | if (!NT_SUCCESS(status)) { 116 | return status; 117 | } 118 | 119 | RtlZeroMemory(outputBuffer, outputBufferSize); 120 | 121 | WDF_MEMORY_DESCRIPTOR inputMemDesc; 122 | WDF_MEMORY_DESCRIPTOR outputMemDesc; 123 | WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputMemDesc, &inputBuffer, (ULONG)sizeof(inputBuffer)); 124 | WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&outputMemDesc, outputMemory, NULL); 125 | 126 | status = WdfIoTargetSendInternalIoctlSynchronously( 127 | WdfDeviceGetIoTarget(FxDevice), 128 | NULL, 129 | IOCTL_ACPI_EVAL_METHOD_EX, 130 | &inputMemDesc, 131 | &outputMemDesc, 132 | NULL, 133 | NULL 134 | ); 135 | if (!NT_SUCCESS(status)) { 136 | goto Exit; 137 | } 138 | 139 | if (outputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) { 140 | goto Exit; 141 | } 142 | 143 | if (outputBuffer->Count < 1) { 144 | goto Exit; 145 | } 146 | 147 | uint32_t uid; 148 | if (outputBuffer->Argument[0].DataLength >= 4) { 149 | uid = *(uint32_t*)outputBuffer->Argument->Data; 150 | } 151 | else if (outputBuffer->Argument[0].DataLength >= 2) { 152 | uid = *(uint16_t*)outputBuffer->Argument->Data; 153 | } 154 | else { 155 | uid = *(uint8_t*)outputBuffer->Argument->Data; 156 | } 157 | if (PUID) { 158 | *PUID = uid; 159 | } 160 | else { 161 | status = STATUS_ACPI_INVALID_ARGUMENT; 162 | } 163 | Exit: 164 | if (outputMemory != WDF_NO_HANDLE) { 165 | WdfObjectDelete(outputMemory); 166 | } 167 | return status; 168 | } 169 | 170 | NTSTATUS 171 | StartCodec( 172 | PRT1015_CONTEXT pDevice 173 | ) { 174 | NTSTATUS status = STATUS_SUCCESS; 175 | if (!pDevice->SetUID) { 176 | status = STATUS_ACPI_INVALID_DATA; 177 | return status; 178 | } 179 | 180 | 181 | uint16_t val = 0; 182 | rt1015_reg_read(pDevice, RT1015_DEVICE_ID, &val); 183 | if ((val != RT1015_DEVICE_ID_VAL) && (val != RT1015_DEVICE_ID_VAL2)) { 184 | return STATUS_INVALID_DEVICE_STATE; 185 | } 186 | 187 | //left/right diffs 188 | // RT1015_DUM_RW1 189 | // RT1015_PAD_DRV2 190 | // RT1015_SPK_DC_DETECT1 191 | 192 | struct reg regsCommon[] = { 193 | {RT1015_PLL1, 0x0816}, 194 | {RT1015_PLL2, 0x0004}, 195 | {RT1015_CLK_DET, 0x8800}, 196 | {RT1015_SIL_DET, 0x0143}, 197 | {RT1015_TDM_MASTER, 0x0000}, 198 | {RT1015_TDM1_4, 0x0101}, 199 | {RT1015_PWR4, 0x00B2}, 200 | {RT1015_PWR9, 0xAA60}, 201 | {RT1015_SMART_BST_CTRL1, 0xe188}, 202 | {RT1015_PWR_STATE_CTRL, 0x02ee}, 203 | {RT1015_MONO_DYNA_CTRL, 0x0010} 204 | }; 205 | 206 | status = rt1015_reg_burstWrite(pDevice, regsCommon, sizeof(regsCommon) / sizeof(struct reg)); 207 | if (!NT_SUCCESS(status)) { 208 | return status; 209 | } 210 | 211 | if (pDevice->UID == 0) { 212 | status = rt1015_reg_write(pDevice, RT1015_DUM_RW1, 0x0006); 213 | if (!NT_SUCCESS(status)) { 214 | return status; 215 | } 216 | status = rt1015_reg_write(pDevice, RT1015_PAD_DRV2, 0x004c); //don't need this 217 | if (!NT_SUCCESS(status)) { 218 | return status; 219 | } 220 | status = rt1015_reg_write(pDevice, RT1015_SPK_DC_DETECT1, 0x1c6d); 221 | if (!NT_SUCCESS(status)) { 222 | return status; 223 | } 224 | } 225 | else if (pDevice->UID == 1) { 226 | status = rt1015_reg_write(pDevice, RT1015_DUM_RW1, 0x0007); 227 | if (!NT_SUCCESS(status)) { 228 | return status; 229 | } 230 | status = rt1015_reg_write(pDevice, RT1015_PAD_DRV2, 0x005c); 231 | if (!NT_SUCCESS(status)) { 232 | return status; 233 | } 234 | status = rt1015_reg_write(pDevice, RT1015_SPK_DC_DETECT1, 0x1c6c); 235 | if (!NT_SUCCESS(status)) { 236 | return status; 237 | } 238 | } 239 | 240 | pDevice->DevicePoweredOn = TRUE; 241 | return status; 242 | } 243 | 244 | NTSTATUS 245 | StopCodec( 246 | PRT1015_CONTEXT pDevice 247 | ) { 248 | NTSTATUS status; 249 | 250 | status = rt1015_reg_write(pDevice, RT1015_RESET, 0); 251 | 252 | pDevice->DevicePoweredOn = FALSE; 253 | return status; 254 | } 255 | 256 | int CsAudioArg2 = 1; 257 | 258 | VOID 259 | CSAudioRegisterEndpoint( 260 | PRT1015_CONTEXT pDevice 261 | ) { 262 | CsAudioArg arg; 263 | RtlZeroMemory(&arg, sizeof(CsAudioArg)); 264 | arg.argSz = sizeof(CsAudioArg); 265 | arg.endpointType = CSAudioEndpointTypeSpeaker; 266 | arg.endpointRequest = CSAudioEndpointRegister; 267 | ExNotifyCallback(pDevice->CSAudioAPICallback, &arg, &CsAudioArg2); 268 | } 269 | 270 | VOID 271 | CsAudioCallbackFunction( 272 | IN PRT1015_CONTEXT pDevice, 273 | CsAudioArg* arg, 274 | PVOID Argument2 275 | ) { 276 | if (!pDevice) { 277 | return; 278 | } 279 | 280 | if (Argument2 == &CsAudioArg2) { 281 | return; 282 | } 283 | 284 | pDevice->CSAudioManaged = TRUE; 285 | 286 | CsAudioArg localArg; 287 | RtlZeroMemory(&localArg, sizeof(CsAudioArg)); 288 | RtlCopyMemory(&localArg, arg, min(arg->argSz, sizeof(CsAudioArg))); 289 | 290 | if (localArg.endpointType == CSAudioEndpointTypeDSP && localArg.endpointRequest == CSAudioEndpointRegister) { 291 | CSAudioRegisterEndpoint(pDevice); 292 | } 293 | else if (localArg.endpointType != CSAudioEndpointTypeSpeaker) { 294 | return; 295 | } 296 | 297 | if (localArg.endpointRequest == CSAudioEndpointStop) { 298 | if (pDevice->CSAudioRequestsOn) { 299 | WdfDeviceResumeIdle(pDevice->FxDevice); 300 | pDevice->CSAudioRequestsOn = FALSE; 301 | } 302 | } 303 | if (localArg.endpointRequest == CSAudioEndpointStart) { 304 | if (!pDevice->CSAudioRequestsOn) { 305 | WdfDeviceStopIdle(pDevice->FxDevice, TRUE); 306 | pDevice->CSAudioRequestsOn = TRUE; 307 | } 308 | } 309 | } 310 | 311 | NTSTATUS 312 | OnPrepareHardware( 313 | _In_ WDFDEVICE FxDevice, 314 | _In_ WDFCMRESLIST FxResourcesRaw, 315 | _In_ WDFCMRESLIST FxResourcesTranslated 316 | ) 317 | /*++ 318 | 319 | Routine Description: 320 | 321 | This routine caches the SPB resource connection ID. 322 | 323 | Arguments: 324 | 325 | FxDevice - a handle to the framework device object 326 | FxResourcesRaw - list of translated hardware resources that 327 | the PnP manager has assigned to the device 328 | FxResourcesTranslated - list of raw hardware resources that 329 | the PnP manager has assigned to the device 330 | 331 | Return Value: 332 | 333 | Status 334 | 335 | --*/ 336 | { 337 | PRT1015_CONTEXT pDevice = GetDeviceContext(FxDevice); 338 | BOOLEAN fSpbResourceFound = FALSE; 339 | NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES; 340 | 341 | UNREFERENCED_PARAMETER(FxResourcesRaw); 342 | 343 | // 344 | // Parse the peripheral's resources. 345 | // 346 | 347 | ULONG resourceCount = WdfCmResourceListGetCount(FxResourcesTranslated); 348 | 349 | for (ULONG i = 0; i < resourceCount; i++) 350 | { 351 | PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor; 352 | UCHAR Class; 353 | UCHAR Type; 354 | 355 | pDescriptor = WdfCmResourceListGetDescriptor( 356 | FxResourcesTranslated, i); 357 | 358 | switch (pDescriptor->Type) 359 | { 360 | case CmResourceTypeConnection: 361 | // 362 | // Look for I2C or SPI resource and save connection ID. 363 | // 364 | Class = pDescriptor->u.Connection.Class; 365 | Type = pDescriptor->u.Connection.Type; 366 | if (Class == CM_RESOURCE_CONNECTION_CLASS_SERIAL && 367 | Type == CM_RESOURCE_CONNECTION_TYPE_SERIAL_I2C) 368 | { 369 | if (fSpbResourceFound == FALSE) 370 | { 371 | status = STATUS_SUCCESS; 372 | pDevice->I2CContext.I2cResHubId.LowPart = pDescriptor->u.Connection.IdLowPart; 373 | pDevice->I2CContext.I2cResHubId.HighPart = pDescriptor->u.Connection.IdHighPart; 374 | fSpbResourceFound = TRUE; 375 | } 376 | else 377 | { 378 | } 379 | } 380 | break; 381 | default: 382 | // 383 | // Ignoring all other resource types. 384 | // 385 | break; 386 | } 387 | } 388 | 389 | // 390 | // An SPB resource is required. 391 | // 392 | 393 | if (fSpbResourceFound == FALSE) 394 | { 395 | status = STATUS_NOT_FOUND; 396 | } 397 | 398 | status = SpbTargetInitialize(FxDevice, &pDevice->I2CContext); 399 | 400 | if (!NT_SUCCESS(status)) 401 | { 402 | return status; 403 | } 404 | 405 | status = GetDeviceUID(FxDevice, &pDevice->UID); 406 | if (!NT_SUCCESS(status)) { 407 | return status; 408 | } 409 | pDevice->SetUID = TRUE; 410 | 411 | return status; 412 | } 413 | 414 | NTSTATUS 415 | OnReleaseHardware( 416 | _In_ WDFDEVICE FxDevice, 417 | _In_ WDFCMRESLIST FxResourcesTranslated 418 | ) 419 | /*++ 420 | 421 | Routine Description: 422 | 423 | Arguments: 424 | 425 | FxDevice - a handle to the framework device object 426 | FxResourcesTranslated - list of raw hardware resources that 427 | the PnP manager has assigned to the device 428 | 429 | Return Value: 430 | 431 | Status 432 | 433 | --*/ 434 | { 435 | PRT1015_CONTEXT pDevice = GetDeviceContext(FxDevice); 436 | NTSTATUS status = STATUS_SUCCESS; 437 | 438 | UNREFERENCED_PARAMETER(FxResourcesTranslated); 439 | 440 | SpbTargetDeinitialize(FxDevice, &pDevice->I2CContext); 441 | 442 | if (pDevice->CSAudioAPICallbackObj) { 443 | ExUnregisterCallback(pDevice->CSAudioAPICallbackObj); 444 | pDevice->CSAudioAPICallbackObj = NULL; 445 | } 446 | 447 | if (pDevice->CSAudioAPICallback) { 448 | ObfDereferenceObject(pDevice->CSAudioAPICallback); 449 | pDevice->CSAudioAPICallback = NULL; 450 | } 451 | 452 | return status; 453 | } 454 | 455 | NTSTATUS 456 | OnSelfManagedIoInit( 457 | _In_ 458 | WDFDEVICE FxDevice 459 | ) { 460 | PRT1015_CONTEXT pDevice = GetDeviceContext(FxDevice); 461 | NTSTATUS status = STATUS_SUCCESS; 462 | 463 | // CS Audio Callback 464 | 465 | UNICODE_STRING CSAudioCallbackAPI; 466 | RtlInitUnicodeString(&CSAudioCallbackAPI, L"\\CallBack\\CsAudioCallbackAPI"); 467 | 468 | 469 | OBJECT_ATTRIBUTES attributes; 470 | InitializeObjectAttributes(&attributes, 471 | &CSAudioCallbackAPI, 472 | OBJ_KERNEL_HANDLE | OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 473 | NULL, 474 | NULL 475 | ); 476 | status = ExCreateCallback(&pDevice->CSAudioAPICallback, &attributes, TRUE, TRUE); 477 | if (!NT_SUCCESS(status)) { 478 | 479 | return status; 480 | } 481 | 482 | pDevice->CSAudioAPICallbackObj = ExRegisterCallback(pDevice->CSAudioAPICallback, 483 | CsAudioCallbackFunction, 484 | pDevice 485 | ); 486 | if (!pDevice->CSAudioAPICallbackObj) { 487 | 488 | return STATUS_NO_CALLBACK_ACTIVE; 489 | } 490 | 491 | CSAudioRegisterEndpoint(pDevice); 492 | 493 | return status; 494 | } 495 | 496 | NTSTATUS 497 | OnD0Entry( 498 | _In_ WDFDEVICE FxDevice, 499 | _In_ WDF_POWER_DEVICE_STATE FxPreviousState 500 | ) 501 | /*++ 502 | 503 | Routine Description: 504 | 505 | This routine allocates objects needed by the driver. 506 | 507 | Arguments: 508 | 509 | FxDevice - a handle to the framework device object 510 | FxPreviousState - previous power state 511 | 512 | Return Value: 513 | 514 | Status 515 | 516 | --*/ 517 | { 518 | UNREFERENCED_PARAMETER(FxPreviousState); 519 | 520 | PRT1015_CONTEXT pDevice = GetDeviceContext(FxDevice); 521 | NTSTATUS status = STATUS_SUCCESS; 522 | 523 | status = StartCodec(pDevice); 524 | 525 | return status; 526 | } 527 | 528 | NTSTATUS 529 | OnD0Exit( 530 | _In_ WDFDEVICE FxDevice, 531 | _In_ WDF_POWER_DEVICE_STATE FxPreviousState 532 | ) 533 | /*++ 534 | 535 | Routine Description: 536 | 537 | This routine destroys objects needed by the driver. 538 | 539 | Arguments: 540 | 541 | FxDevice - a handle to the framework device object 542 | FxPreviousState - previous power state 543 | 544 | Return Value: 545 | 546 | Status 547 | 548 | --*/ 549 | { 550 | UNREFERENCED_PARAMETER(FxPreviousState); 551 | 552 | PRT1015_CONTEXT pDevice = GetDeviceContext(FxDevice); 553 | NTSTATUS status = STATUS_SUCCESS; 554 | 555 | status = StopCodec(pDevice); 556 | 557 | return STATUS_SUCCESS; 558 | } 559 | 560 | NTSTATUS 561 | Rt1015EvtDeviceAdd( 562 | IN WDFDRIVER Driver, 563 | IN PWDFDEVICE_INIT DeviceInit 564 | ) 565 | { 566 | NTSTATUS status = STATUS_SUCCESS; 567 | WDF_IO_QUEUE_CONFIG queueConfig; 568 | WDF_OBJECT_ATTRIBUTES attributes; 569 | WDFDEVICE device; 570 | WDFQUEUE queue; 571 | PRT1015_CONTEXT devContext; 572 | 573 | UNREFERENCED_PARAMETER(Driver); 574 | 575 | PAGED_CODE(); 576 | 577 | Rt1015Print(DEBUG_LEVEL_INFO, DBG_PNP, 578 | "Rt1015EvtDeviceAdd called\n"); 579 | 580 | { 581 | WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks; 582 | WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks); 583 | 584 | pnpCallbacks.EvtDevicePrepareHardware = OnPrepareHardware; 585 | pnpCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware; 586 | pnpCallbacks.EvtDeviceSelfManagedIoInit = OnSelfManagedIoInit; 587 | pnpCallbacks.EvtDeviceD0Entry = OnD0Entry; 588 | pnpCallbacks.EvtDeviceD0Exit = OnD0Exit; 589 | 590 | WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks); 591 | } 592 | 593 | // 594 | // Setup the device context 595 | // 596 | 597 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, RT1015_CONTEXT); 598 | 599 | // 600 | // Create a framework device object.This call will in turn create 601 | // a WDM device object, attach to the lower stack, and set the 602 | // appropriate flags and attributes. 603 | // 604 | 605 | status = WdfDeviceCreate(&DeviceInit, &attributes, &device); 606 | 607 | if (!NT_SUCCESS(status)) 608 | { 609 | Rt1015Print(DEBUG_LEVEL_ERROR, DBG_PNP, 610 | "WdfDeviceCreate failed with status code 0x%x\n", status); 611 | 612 | return status; 613 | } 614 | 615 | { 616 | WDF_DEVICE_STATE deviceState; 617 | WDF_DEVICE_STATE_INIT(&deviceState); 618 | 619 | deviceState.NotDisableable = WdfFalse; 620 | WdfDeviceSetDeviceState(device, &deviceState); 621 | } 622 | 623 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchParallel); 624 | 625 | queueConfig.EvtIoInternalDeviceControl = Rt1015EvtInternalDeviceControl; 626 | 627 | status = WdfIoQueueCreate(device, 628 | &queueConfig, 629 | WDF_NO_OBJECT_ATTRIBUTES, 630 | &queue 631 | ); 632 | 633 | if (!NT_SUCCESS(status)) 634 | { 635 | Rt1015Print(DEBUG_LEVEL_ERROR, DBG_PNP, 636 | "WdfIoQueueCreate failed 0x%x\n", status); 637 | 638 | return status; 639 | } 640 | 641 | // 642 | // Create manual I/O queue to take care of hid report read requests 643 | // 644 | 645 | devContext = GetDeviceContext(device); 646 | 647 | devContext->FxDevice = device; 648 | 649 | WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual); 650 | 651 | queueConfig.PowerManaged = WdfTrue; 652 | 653 | status = WdfIoQueueCreate(device, 654 | &queueConfig, 655 | WDF_NO_OBJECT_ATTRIBUTES, 656 | &devContext->ReportQueue 657 | ); 658 | 659 | if (!NT_SUCCESS(status)) 660 | { 661 | Rt1015Print(DEBUG_LEVEL_ERROR, DBG_PNP, 662 | "WdfIoQueueCreate failed 0x%x\n", status); 663 | 664 | return status; 665 | } 666 | 667 | WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS IdleSettings; 668 | 669 | WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&IdleSettings, IdleCannotWakeFromS0); 670 | IdleSettings.IdleTimeoutType = SystemManagedIdleTimeoutWithHint; 671 | IdleSettings.IdleTimeout = 1000; 672 | IdleSettings.Enabled = WdfTrue; 673 | 674 | WdfDeviceAssignS0IdleSettings(devContext->FxDevice, &IdleSettings); 675 | 676 | return status; 677 | } 678 | 679 | VOID 680 | Rt1015EvtInternalDeviceControl( 681 | IN WDFQUEUE Queue, 682 | IN WDFREQUEST Request, 683 | IN size_t OutputBufferLength, 684 | IN size_t InputBufferLength, 685 | IN ULONG IoControlCode 686 | ) 687 | { 688 | NTSTATUS status = STATUS_SUCCESS; 689 | WDFDEVICE device; 690 | PRT1015_CONTEXT devContext; 691 | 692 | UNREFERENCED_PARAMETER(OutputBufferLength); 693 | UNREFERENCED_PARAMETER(InputBufferLength); 694 | 695 | device = WdfIoQueueGetDevice(Queue); 696 | devContext = GetDeviceContext(device); 697 | 698 | switch (IoControlCode) 699 | { 700 | default: 701 | status = STATUS_NOT_SUPPORTED; 702 | break; 703 | } 704 | 705 | WdfRequestComplete(Request, status); 706 | 707 | return; 708 | } --------------------------------------------------------------------------------