├── .gitattributes ├── LICENSE.txt ├── README.md ├── croseccodec ├── trace.h ├── croseccodec.inf ├── driver.h ├── croseccodec.h ├── croseccodec.vcxproj └── croseccodec.c ├── croseccodec.sln ├── .gitignore └── croseccodec Package └── croseccodec Package.vcxproj /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2022 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Chrome EC Audio Codec Driver 2 | 3 | * NOTE: This driver requires the https://github.com/coolstar/crosecbus driver to be present, as well as the correct ACPI tables set up by coreboot 4 | 5 | Initializes the Chrome EC Audio Codec to use 16-bit 48 Khz Audio Streams 6 | 7 | * Wake on Voice is not currently implemented 8 | 9 | Note: 10 | * Intel SST and AMD ACP proprietary drivers do NOT have documented interfaces, so this driver will not work with them. 11 | * Using this driver on chromebooks with this audio codec will require using CoolStar ACP Audio or CoolStar SOF Audio 12 | * Most chromebooks with Chrome EC Codec use it for DMIC only. This driver waits 2 seconds before initialization to allow the main codec to start generating a clock signal 13 | 14 | Tested on HP Chromebook 14b (Ryzen 3 3250C) -------------------------------------------------------------------------------- /croseccodec/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 | -------------------------------------------------------------------------------- /croseccodec/croseccodec.inf: -------------------------------------------------------------------------------- 1 | ;/*++ 2 | ; 3 | ;Copyright (c) CoolStar. All rights reserved. 4 | ; 5 | ;Module Name: 6 | ; croseccodec.inf 7 | ; 8 | ;Abstract: 9 | ; INF file for installing the CR50 I2C 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 = 12/16/2021,1.0.0 20 | CatalogFile = croseccodec.cat 21 | PnpLockdown = 1 22 | 23 | [DestinationDirs] 24 | DefaultDestDir = 12 25 | 26 | ; ================= Class section ===================== 27 | 28 | [SourceDisksNames] 29 | 1 = %DiskId1%,,,"" 30 | 31 | [SourceDisksFiles] 32 | croseccodec.sys = 1,, 33 | 34 | ;***************************************** 35 | ; CrosEcCodec Install Section 36 | ;***************************************** 37 | 38 | [Manufacturer] 39 | %StdMfg%=Standard,NT$ARCH$.10.0...14393 40 | 41 | ; Decorated model section take precedence over undecorated 42 | ; ones on XP and later. 43 | [Standard.NT$ARCH$.10.0...14393] 44 | %CrosEcCodec.DeviceDesc%=CrosEcCodec_Device, ACPI\GOOG0013 45 | 46 | [CrosEcCodec_Device.NT] 47 | CopyFiles=Drivers_Dir 48 | 49 | [CrosEcCodec_Device.NT.HW] 50 | AddReg=CrosEcCodec_AddReg 51 | 52 | [Drivers_Dir] 53 | croseccodec.sys 54 | 55 | [CrosEcCodec_AddReg] 56 | ; Set to 1 to connect the first interrupt resource found, 0 to leave disconnected 57 | HKR,Settings,"ConnectInterrupt",0x00010001,0 58 | 59 | ;-------------- Service installation 60 | [CrosEcCodec_Device.NT.Services] 61 | AddService = CrosEcCodec,%SPSVCINST_ASSOCSERVICE%, CrosEcCodec_Service_Inst 62 | 63 | ; -------------- CrosEcCodec driver install sections 64 | [CrosEcCodec_Service_Inst] 65 | DisplayName = %CrosEcCodec.SVCDESC% 66 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 67 | StartType = 3 ; SERVICE_DEMAND_START 68 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 69 | ServiceBinary = %12%\croseccodec.sys 70 | LoadOrderGroup = Base 71 | 72 | [Strings] 73 | SPSVCINST_ASSOCSERVICE= 0x00000002 74 | StdMfg = "CoolStar" 75 | DiskId1 = "Chrome EC Installation Disk #1" 76 | CrosEcCodec.DeviceDesc = "Chromebook EC Audio" 77 | CrosEcCodec.SVCDESC = "Chrome EC Service" 78 | -------------------------------------------------------------------------------- /croseccodec.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31829.152 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "croseccodec", "croseccodec\croseccodec.vcxproj", "{B3E71397-9BE4-492B-AAED-4D056E59CB1F}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "croseccodec Package", "croseccodec Package\croseccodec Package.vcxproj", "{EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F} = {B3E71397-9BE4-492B-AAED-4D056E59CB1F} 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Win10 Debug|Win32 = Win10 Debug|Win32 16 | Win10 Debug|x64 = Win10 Debug|x64 17 | Win10 Release|Win32 = Win10 Release|Win32 18 | Win10 Release|x64 = Win10 Release|x64 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Debug|Win32.ActiveCfg = Win10 Debug|Win32 22 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Debug|Win32.Build.0 = Win10 Debug|Win32 23 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Debug|Win32.Deploy.0 = Win10 Debug|Win32 24 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Debug|x64.ActiveCfg = Win10 Debug|x64 25 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Debug|x64.Build.0 = Win10 Debug|x64 26 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Debug|x64.Deploy.0 = Win10 Debug|x64 27 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Release|Win32.ActiveCfg = Win10 Release|Win32 28 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Release|Win32.Build.0 = Win10 Release|Win32 29 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Release|Win32.Deploy.0 = Win10 Release|Win32 30 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Release|x64.ActiveCfg = Win10 Release|x64 31 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Release|x64.Build.0 = Win10 Release|x64 32 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F}.Win10 Release|x64.Deploy.0 = Win10 Release|x64 33 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Debug|Win32.ActiveCfg = Win10 Debug|Win32 34 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Debug|Win32.Build.0 = Win10 Debug|Win32 35 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Debug|Win32.Deploy.0 = Win10 Debug|Win32 36 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Debug|x64.ActiveCfg = Win10 Debug|x64 37 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Debug|x64.Build.0 = Win10 Debug|x64 38 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Debug|x64.Deploy.0 = Win10 Debug|x64 39 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Release|Win32.ActiveCfg = Win10 Release|Win32 40 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Release|Win32.Build.0 = Win10 Release|Win32 41 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Release|Win32.Deploy.0 = Win10 Release|Win32 42 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Release|x64.ActiveCfg = Win10 Release|x64 43 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Release|x64.Build.0 = Win10 Release|x64 44 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B}.Win10 Release|x64.Deploy.0 = Win10 Release|x64 45 | EndGlobalSection 46 | GlobalSection(SolutionProperties) = preSolution 47 | HideSolutionNode = FALSE 48 | EndGlobalSection 49 | GlobalSection(ExtensibilityGlobals) = postSolution 50 | SolutionGuid = {86D249D6-FF1E-41F4-AA9B-3813428D6C1A} 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /croseccodec/driver.h: -------------------------------------------------------------------------------- 1 | #if !defined(_CROSECCODEC_H_) 2 | #define _CROSECCODEC_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 "croseccodec.h" 16 | 17 | // 18 | // String definitions 19 | // 20 | 21 | #define DRIVERNAME "croseccodec.sys: " 22 | 23 | #define CROSECCODEC_POOL_TAG (ULONG) 'CRAU' 24 | #define CROSECCODEC_HARDWARE_IDS L"CoolStar\\GOOG0012\0\0" 25 | #define CROSECCODEC_HARDWARE_IDS_LENGTH sizeof(CROSECCODEC_HARDWARE_IDS) 26 | 27 | #define NTDEVICE_NAME_STRING L"\\Device\\GOOG0012" 28 | #define SYMBOLIC_NAME_STRING L"\\DosDevices\\GOOG0012" 29 | 30 | #define true 1 31 | #define false 0 32 | 33 | typedef struct _CROSEC_COMMAND { 34 | UINT32 Version; 35 | UINT32 Command; 36 | UINT32 OutSize; 37 | UINT32 InSize; 38 | UINT32 Result; 39 | UINT8 Data[]; 40 | } CROSEC_COMMAND, *PCROSEC_COMMAND; 41 | 42 | typedef 43 | NTSTATUS 44 | (*PCROSEC_CMD_XFER_STATUS)( 45 | IN PVOID Context, 46 | OUT PCROSEC_COMMAND Msg 47 | ); 48 | 49 | typedef 50 | BOOLEAN 51 | (*PCROSEC_CHECK_FEATURES)( 52 | IN PVOID Context, 53 | IN INT Feature 54 | ); 55 | 56 | DEFINE_GUID(GUID_CROSEC_INTERFACE_STANDARD, 57 | 0xd7062676, 0xe3a4, 0x11ec, 0xa6, 0xc4, 0x24, 0x4b, 0xfe, 0x99, 0x46, 0xd0); 58 | 59 | /*DEFINE_GUID(GUID_DEVICE_PROPERTIES, 60 | 0xdaffd814, 0x6eba, 0x4d8c, 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01);*/ //Windows defender false positive 61 | 62 | // 63 | // Interface for getting and setting power level etc., 64 | // 65 | typedef struct _CROSEC_INTERFACE_STANDARD { 66 | INTERFACE InterfaceHeader; 67 | PCROSEC_CMD_XFER_STATUS CmdXferStatus; 68 | PCROSEC_CHECK_FEATURES CheckFeatures; 69 | } CROSEC_INTERFACE_STANDARD, * PCROSEC_INTERFACE_STANDARD; 70 | 71 | typedef struct _CROSECCODEC_CONTEXT 72 | { 73 | // 74 | // Handle back to the WDFDEVICE 75 | // 76 | 77 | WDFDEVICE FxDevice; 78 | 79 | PVOID CrosEcBusContext; 80 | 81 | PCROSEC_CMD_XFER_STATUS CrosEcCmdXferStatus; 82 | 83 | WDFIOTARGET busIoTarget; 84 | 85 | } CROSECCODEC_CONTEXT, *PCROSECCODEC_CONTEXT; 86 | 87 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CROSECCODEC_CONTEXT, GetDeviceContext) 88 | 89 | // 90 | // Function definitions 91 | // 92 | 93 | DRIVER_INITIALIZE DriverEntry; 94 | 95 | EVT_WDF_DRIVER_UNLOAD CrosEcCodecDriverUnload; 96 | 97 | EVT_WDF_DRIVER_DEVICE_ADD CrosEcCodecEvtDeviceAdd; 98 | 99 | EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL CrosEcCodecEvtInternalDeviceControl; 100 | 101 | // 102 | // Helper macros 103 | // 104 | 105 | #define DEBUG_LEVEL_ERROR 1 106 | #define DEBUG_LEVEL_INFO 2 107 | #define DEBUG_LEVEL_VERBOSE 3 108 | 109 | #define DBG_INIT 1 110 | #define DBG_PNP 2 111 | #define DBG_IOCTL 4 112 | 113 | #if 0 114 | #define CrosEcCodecPrint(dbglevel, dbgcatagory, fmt, ...) { \ 115 | if (CrosEcCodecDebugLevel >= dbglevel && \ 116 | (CrosEcCodecDebugCatagories && dbgcatagory)) \ 117 | { \ 118 | DbgPrint(DRIVERNAME); \ 119 | DbgPrint(fmt, __VA_ARGS__); \ 120 | } \ 121 | } 122 | #else 123 | #define CrosEcCodecPrint(dbglevel, fmt, ...) { \ 124 | } 125 | #endif 126 | #endif -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /croseccodec Package/croseccodec Package.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Win10 Debug 6 | Win32 7 | 8 | 9 | Win10 Debug 10 | x64 11 | 12 | 13 | Win10 Release 14 | Win32 15 | 16 | 17 | Win10 Release 18 | x64 19 | 20 | 21 | 22 | {EA676041-89D8-4ACF-A48B-F11CA9F5DD8B} 23 | {4605da2c-74a5-4865-98e1-152ef136825f} 24 | v4.5 25 | 11.0 26 | Win8.1 Debug 27 | Win32 28 | croseccodec_Package 29 | 10.0.22000.0 30 | croseccodec Package 31 | 32 | 33 | 34 | WindowsV6.3 35 | false 36 | WindowsKernelModeDriver10.0 37 | Utility 38 | Package 39 | true 40 | 41 | 42 | Windows8 43 | true 44 | WindowsKernelModeDriver10.0 45 | Utility 46 | Package 47 | true 48 | 49 | 50 | WindowsV6.3 51 | false 52 | WindowsKernelModeDriver10.0 53 | Utility 54 | Package 55 | true 56 | 57 | 58 | Windows8 59 | true 60 | WindowsKernelModeDriver10.0 61 | Utility 62 | Package 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | DbgengKernelDebugger 75 | False 76 | True 77 | 78 | 79 | 80 | False 81 | False 82 | True 83 | 84 | 133563 85 | 86 | 87 | DbgengKernelDebugger 88 | False 89 | True 90 | 91 | 92 | 93 | False 94 | False 95 | True 96 | 97 | 133563 98 | 99 | 100 | DbgengKernelDebugger 101 | False 102 | True 103 | 104 | 105 | 106 | False 107 | False 108 | True 109 | 110 | 133563 111 | 112 | 113 | DbgengKernelDebugger 114 | False 115 | True 116 | 117 | 118 | 119 | False 120 | False 121 | True 122 | 123 | 133563 124 | 125 | 126 | 127 | SHA256 128 | 129 | 130 | 131 | 132 | SHA256 133 | 134 | 135 | 136 | 137 | SHA256 138 | 139 | 140 | 141 | 142 | SHA256 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | {b3e71397-9be4-492b-aaed-4d056e59cb1f} 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /croseccodec/croseccodec.h: -------------------------------------------------------------------------------- 1 | #ifndef __CROS_EC_REGS_H__ 2 | #define __CROS_EC_REGS_H__ 3 | 4 | #define BIT(nr) (1UL << (nr)) 5 | 6 | /* Commands for audio codec. */ 7 | #define EC_CMD_EC_CODEC 0x00BC 8 | 9 | enum ec_codec_subcmd { 10 | EC_CODEC_GET_CAPABILITIES = 0x0, 11 | EC_CODEC_GET_SHM_ADDR = 0x1, 12 | EC_CODEC_SET_SHM_ADDR = 0x2, 13 | EC_CODEC_SUBCMD_COUNT, 14 | }; 15 | 16 | enum ec_codec_cap { 17 | EC_CODEC_CAP_WOV_AUDIO_SHM = 0, 18 | EC_CODEC_CAP_WOV_LANG_SHM = 1, 19 | EC_CODEC_CAP_LAST = 32, 20 | }; 21 | 22 | enum ec_codec_shm_id { 23 | EC_CODEC_SHM_ID_WOV_AUDIO = 0x0, 24 | EC_CODEC_SHM_ID_WOV_LANG = 0x1, 25 | EC_CODEC_SHM_ID_LAST, 26 | }; 27 | 28 | enum ec_codec_shm_type { 29 | EC_CODEC_SHM_TYPE_EC_RAM = 0x0, 30 | EC_CODEC_SHM_TYPE_SYSTEM_RAM = 0x1, 31 | }; 32 | 33 | #include 34 | 35 | struct ec_param_ec_codec_get_shm_addr { 36 | UINT8 shm_id; 37 | UINT8 reserved[3]; 38 | }; 39 | 40 | #include 41 | 42 | #include 43 | 44 | struct ec_param_ec_codec_set_shm_addr { 45 | UINT64 phys_addr; 46 | UINT32 len; 47 | UINT8 shm_id; 48 | UINT8 reserved[3]; 49 | }; 50 | 51 | struct ec_param_ec_codec { 52 | UINT8 cmd; /* enum ec_codec_subcmd */ 53 | UINT8 reserved[3]; 54 | 55 | union { 56 | struct ec_param_ec_codec_get_shm_addr 57 | get_shm_addr_param; 58 | struct ec_param_ec_codec_set_shm_addr 59 | set_shm_addr_param; 60 | }; 61 | }; 62 | 63 | struct ec_response_ec_codec_get_capabilities { 64 | UINT32 capabilities; 65 | }; 66 | 67 | struct ec_response_ec_codec_get_shm_addr { 68 | UINT64 phys_addr; 69 | UINT32 len; 70 | UINT8 type; 71 | UINT8 reserved[3]; 72 | }; 73 | 74 | #include 75 | 76 | /*****************************************************************************/ 77 | 78 | /* Commands for DMIC on audio codec. */ 79 | #define EC_CMD_EC_CODEC_DMIC 0x00BD 80 | 81 | enum ec_codec_dmic_subcmd { 82 | EC_CODEC_DMIC_GET_MAX_GAIN = 0x0, 83 | EC_CODEC_DMIC_SET_GAIN_IDX = 0x1, 84 | EC_CODEC_DMIC_GET_GAIN_IDX = 0x2, 85 | EC_CODEC_DMIC_SUBCMD_COUNT, 86 | }; 87 | 88 | enum ec_codec_dmic_channel { 89 | EC_CODEC_DMIC_CHANNEL_0 = 0x0, 90 | EC_CODEC_DMIC_CHANNEL_1 = 0x1, 91 | EC_CODEC_DMIC_CHANNEL_2 = 0x2, 92 | EC_CODEC_DMIC_CHANNEL_3 = 0x3, 93 | EC_CODEC_DMIC_CHANNEL_4 = 0x4, 94 | EC_CODEC_DMIC_CHANNEL_5 = 0x5, 95 | EC_CODEC_DMIC_CHANNEL_6 = 0x6, 96 | EC_CODEC_DMIC_CHANNEL_7 = 0x7, 97 | EC_CODEC_DMIC_CHANNEL_COUNT, 98 | }; 99 | 100 | #include 101 | 102 | struct ec_param_ec_codec_dmic_set_gain_idx { 103 | UINT8 channel; /* enum ec_codec_dmic_channel */ 104 | UINT8 gain; 105 | UINT8 reserved[2]; 106 | }; 107 | 108 | struct ec_param_ec_codec_dmic_get_gain_idx { 109 | UINT8 channel; /* enum ec_codec_dmic_channel */ 110 | UINT8 reserved[3]; 111 | }; 112 | 113 | #include 114 | 115 | #include 116 | 117 | struct ec_param_ec_codec_dmic { 118 | UINT8 cmd; /* enum ec_codec_dmic_subcmd */ 119 | UINT8 reserved[3]; 120 | 121 | union { 122 | struct ec_param_ec_codec_dmic_set_gain_idx 123 | set_gain_idx_param; 124 | struct ec_param_ec_codec_dmic_get_gain_idx 125 | get_gain_idx_param; 126 | }; 127 | }; 128 | 129 | #include 130 | 131 | #include 132 | 133 | struct ec_response_ec_codec_dmic_get_max_gain { 134 | UINT8 max_gain; 135 | }; 136 | 137 | struct ec_response_ec_codec_dmic_get_gain_idx { 138 | UINT8 gain; 139 | }; 140 | 141 | #include 142 | 143 | /*****************************************************************************/ 144 | 145 | /* Commands for I2S RX on audio codec. */ 146 | 147 | #define EC_CMD_EC_CODEC_I2S_RX 0x00BE 148 | 149 | enum ec_codec_i2s_rx_subcmd { 150 | EC_CODEC_I2S_RX_ENABLE = 0x0, 151 | EC_CODEC_I2S_RX_DISABLE = 0x1, 152 | EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH = 0x2, 153 | EC_CODEC_I2S_RX_SET_DAIFMT = 0x3, 154 | EC_CODEC_I2S_RX_SET_BCLK = 0x4, 155 | EC_CODEC_I2S_RX_RESET = 0x5, 156 | EC_CODEC_I2S_RX_SUBCMD_COUNT, 157 | }; 158 | 159 | enum ec_codec_i2s_rx_sample_depth { 160 | EC_CODEC_I2S_RX_SAMPLE_DEPTH_16 = 0x0, 161 | EC_CODEC_I2S_RX_SAMPLE_DEPTH_24 = 0x1, 162 | EC_CODEC_I2S_RX_SAMPLE_DEPTH_COUNT, 163 | }; 164 | 165 | enum ec_codec_i2s_rx_daifmt { 166 | EC_CODEC_I2S_RX_DAIFMT_I2S = 0x0, 167 | EC_CODEC_I2S_RX_DAIFMT_RIGHT_J = 0x1, 168 | EC_CODEC_I2S_RX_DAIFMT_LEFT_J = 0x2, 169 | EC_CODEC_I2S_RX_DAIFMT_COUNT, 170 | }; 171 | 172 | #include 173 | 174 | struct ec_param_ec_codec_i2s_rx_set_sample_depth { 175 | UINT8 depth; 176 | UINT8 reserved[3]; 177 | }; 178 | 179 | struct ec_param_ec_codec_i2s_rx_set_gain { 180 | UINT8 left; 181 | UINT8 right; 182 | UINT8 reserved[2]; 183 | }; 184 | 185 | struct ec_param_ec_codec_i2s_rx_set_daifmt { 186 | UINT8 daifmt; 187 | UINT8 reserved[3]; 188 | }; 189 | 190 | #include 191 | 192 | #include 193 | 194 | struct ec_param_ec_codec_i2s_rx_set_bclk { 195 | UINT32 bclk; 196 | }; 197 | 198 | struct ec_param_ec_codec_i2s_rx { 199 | UINT8 cmd; /* enum ec_codec_i2s_rx_subcmd */ 200 | UINT8 reserved[3]; 201 | 202 | union { 203 | struct ec_param_ec_codec_i2s_rx_set_sample_depth 204 | set_sample_depth_param; 205 | struct ec_param_ec_codec_i2s_rx_set_daifmt 206 | set_daifmt_param; 207 | struct ec_param_ec_codec_i2s_rx_set_bclk 208 | set_bclk_param; 209 | }; 210 | }; 211 | 212 | #include 213 | 214 | /*****************************************************************************/ 215 | /* Commands for WoV on audio codec. */ 216 | 217 | #define EC_CMD_EC_CODEC_WOV 0x00BF 218 | 219 | enum ec_codec_wov_subcmd { 220 | EC_CODEC_WOV_SET_LANG = 0x0, 221 | EC_CODEC_WOV_SET_LANG_SHM = 0x1, 222 | EC_CODEC_WOV_GET_LANG = 0x2, 223 | EC_CODEC_WOV_ENABLE = 0x3, 224 | EC_CODEC_WOV_DISABLE = 0x4, 225 | EC_CODEC_WOV_READ_AUDIO = 0x5, 226 | EC_CODEC_WOV_READ_AUDIO_SHM = 0x6, 227 | EC_CODEC_WOV_SUBCMD_COUNT, 228 | }; 229 | 230 | #include 231 | 232 | /* 233 | * @hash is SHA256 of the whole language model. 234 | * @total_len indicates the length of whole language model. 235 | * @offset is the cursor from the beginning of the model. 236 | * @buf is the packet buffer. 237 | * @len denotes how many bytes in the buf. 238 | */ 239 | struct ec_param_ec_codec_wov_set_lang { 240 | UINT8 hash[32]; 241 | UINT32 total_len; 242 | UINT32 offset; 243 | UINT8 buf[128]; 244 | UINT32 len; 245 | }; 246 | 247 | struct ec_param_ec_codec_wov_set_lang_shm { 248 | UINT8 hash[32]; 249 | UINT32 total_len; 250 | }; 251 | 252 | struct ec_param_ec_codec_wov { 253 | UINT8 cmd; /* enum ec_codec_wov_subcmd */ 254 | UINT8 reserved[3]; 255 | 256 | union { 257 | struct ec_param_ec_codec_wov_set_lang 258 | set_lang_param; 259 | struct ec_param_ec_codec_wov_set_lang_shm 260 | set_lang_shm_param; 261 | }; 262 | }; 263 | 264 | struct ec_response_ec_codec_wov_get_lang { 265 | UINT8 hash[32]; 266 | }; 267 | 268 | struct ec_response_ec_codec_wov_read_audio { 269 | UINT8 buf[128]; 270 | UINT32 len; 271 | }; 272 | 273 | struct ec_response_ec_codec_wov_read_audio_shm { 274 | UINT32 offset; 275 | UINT32 len; 276 | }; 277 | 278 | #include 279 | 280 | /** 281 | * struct cros_ec_command - Information about a ChromeOS EC command. 282 | * @version: Command version number (often 0). 283 | * @command: Command to send (EC_CMD_...). 284 | * @outsize: Outgoing length in bytes. 285 | * @insize: Max number of bytes to accept from the EC. 286 | * @result: EC's response to the command (separate from communication failure). 287 | * @data: Where to put the incoming data from EC and outgoing data to EC. 288 | */ 289 | struct cros_ec_command { 290 | UINT32 version; 291 | UINT32 command; 292 | UINT32 outsize; 293 | UINT32 insize; 294 | UINT32 result; 295 | UINT8 data[]; 296 | }; 297 | 298 | #endif /* __CROS_EC_REGS_H__ */ -------------------------------------------------------------------------------- /croseccodec/croseccodec.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Win10 Debug 6 | Win32 7 | 8 | 9 | Win10 Debug 10 | x64 11 | 12 | 13 | Win10 Release 14 | Win32 15 | 16 | 17 | Win10 Release 18 | x64 19 | 20 | 21 | 22 | {B3E71397-9BE4-492B-AAED-4D056E59CB1F} 23 | {1bc93793-694f-48fe-9372-81e2b05556fd} 24 | v4.5 25 | 11.0 26 | Win8.1 Debug 27 | Win32 28 | croseccodec 29 | 10.0.22000.0 30 | croseccodec 31 | 32 | 33 | 34 | 35 | 36 | false 37 | WindowsKernelModeDriver10.0 38 | Driver 39 | KMDF 40 | 41 | 42 | 43 | 44 | true 45 | WindowsKernelModeDriver10.0 46 | Driver 47 | KMDF 48 | 49 | 50 | 51 | 52 | false 53 | WindowsKernelModeDriver10.0 54 | Driver 55 | KMDF 56 | 57 | 58 | 59 | 60 | true 61 | WindowsKernelModeDriver10.0 62 | Driver 63 | KMDF 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | DbgengKernelDebugger 75 | 76 | 77 | DbgengKernelDebugger 78 | 79 | 80 | DbgengKernelDebugger 81 | 82 | 83 | DbgengKernelDebugger 84 | 85 | 86 | 87 | true 88 | trace.h 89 | true 90 | false 91 | $(SPB_INC_PATH)\$(SPB_VERSION_MAJOR).$(SPB_VERSION_MINOR);%(AdditionalIncludeDirectories) 92 | 93 | 94 | 1.0.0 95 | 96 | 97 | SHA256 98 | 99 | 100 | $(SPB_LIB_PATH)\$(SPB_VERSION_MAJOR).$(SPB_VERSION_MINOR)\SpbCxStubs.lib;%(AdditionalDependencies) 101 | 102 | 103 | 104 | 105 | true 106 | trace.h 107 | true 108 | false 109 | $(SPB_INC_PATH)\$(SPB_VERSION_MAJOR).$(SPB_VERSION_MINOR);%(AdditionalIncludeDirectories) 110 | 111 | 112 | 1.0.0 113 | 114 | 115 | SHA256 116 | 117 | 118 | $(SPB_LIB_PATH)\$(SPB_VERSION_MAJOR).$(SPB_VERSION_MINOR)\SpbCxStubs.lib;%(AdditionalDependencies) 119 | 120 | 121 | 122 | 123 | true 124 | trace.h 125 | true 126 | false 127 | $(SPB_INC_PATH)\$(SPB_VERSION_MAJOR).$(SPB_VERSION_MINOR);%(AdditionalIncludeDirectories) 128 | 129 | 130 | 1.0.0 131 | 132 | 133 | SHA256 134 | 135 | 136 | $(SPB_LIB_PATH)\$(SPB_VERSION_MAJOR).$(SPB_VERSION_MINOR)\SpbCxStubs.lib;%(AdditionalDependencies) 137 | 138 | 139 | 140 | 141 | true 142 | trace.h 143 | true 144 | false 145 | $(SPB_INC_PATH)\$(SPB_VERSION_MAJOR).$(SPB_VERSION_MINOR);%(AdditionalIncludeDirectories) 146 | 147 | 148 | 1.0.0 149 | 150 | 151 | SHA256 152 | 153 | 154 | $(SPB_LIB_PATH)\$(SPB_VERSION_MAJOR).$(SPB_VERSION_MINOR)\SpbCxStubs.lib;%(AdditionalDependencies) 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /croseccodec/croseccodec.c: -------------------------------------------------------------------------------- 1 | #define DESCRIPTOR_DEF 2 | #include "driver.h" 3 | #include "stdint.h" 4 | 5 | #define bool int 6 | #define MS_IN_US 1000 7 | 8 | static ULONG CrosEcCodecDebugLevel = 100; 9 | static ULONG CrosEcCodecDebugCatagories = DBG_INIT || DBG_PNP || DBG_IOCTL; 10 | 11 | NTSTATUS 12 | DriverEntry( 13 | __in PDRIVER_OBJECT DriverObject, 14 | __in PUNICODE_STRING RegistryPath 15 | ) 16 | { 17 | NTSTATUS status = STATUS_SUCCESS; 18 | WDF_DRIVER_CONFIG config; 19 | WDF_OBJECT_ATTRIBUTES attributes; 20 | 21 | CrosEcCodecPrint(DEBUG_LEVEL_INFO, DBG_INIT, 22 | "Driver Entry\n"); 23 | 24 | WDF_DRIVER_CONFIG_INIT(&config, CrosEcCodecEvtDeviceAdd); 25 | 26 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 27 | 28 | // 29 | // Create a framework driver object to represent our driver. 30 | // 31 | 32 | status = WdfDriverCreate(DriverObject, 33 | RegistryPath, 34 | &attributes, 35 | &config, 36 | WDF_NO_HANDLE 37 | ); 38 | 39 | if (!NT_SUCCESS(status)) 40 | { 41 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_INIT, 42 | "WdfDriverCreate failed with status 0x%x\n", status); 43 | } 44 | 45 | return status; 46 | } 47 | 48 | NTSTATUS ConnectToEc( 49 | _In_ WDFDEVICE FxDevice 50 | ) { 51 | PCROSECCODEC_CONTEXT pDevice = GetDeviceContext(FxDevice); 52 | WDF_OBJECT_ATTRIBUTES objectAttributes; 53 | 54 | WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes); 55 | objectAttributes.ParentObject = FxDevice; 56 | 57 | NTSTATUS status = WdfIoTargetCreate(FxDevice, 58 | &objectAttributes, 59 | &pDevice->busIoTarget 60 | ); 61 | if (!NT_SUCCESS(status)) 62 | { 63 | CrosEcCodecPrint( 64 | DEBUG_LEVEL_ERROR, 65 | DBG_IOCTL, 66 | "Error creating IoTarget object - 0x%x\n", 67 | status); 68 | if (pDevice->busIoTarget) 69 | WdfObjectDelete(pDevice->busIoTarget); 70 | return status; 71 | } 72 | 73 | DECLARE_CONST_UNICODE_STRING(busDosDeviceName, L"\\DosDevices\\GOOG0004"); 74 | 75 | WDF_IO_TARGET_OPEN_PARAMS openParams; 76 | WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME( 77 | &openParams, 78 | &busDosDeviceName, 79 | (GENERIC_READ | GENERIC_WRITE)); 80 | 81 | openParams.ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE; 82 | openParams.CreateDisposition = FILE_OPEN; 83 | openParams.FileAttributes = FILE_ATTRIBUTE_NORMAL; 84 | 85 | CROSEC_INTERFACE_STANDARD CrosEcInterface; 86 | RtlZeroMemory(&CrosEcInterface, sizeof(CrosEcInterface)); 87 | 88 | status = WdfIoTargetOpen(pDevice->busIoTarget, &openParams); 89 | if (!NT_SUCCESS(status)) 90 | { 91 | CrosEcCodecPrint( 92 | DEBUG_LEVEL_ERROR, 93 | DBG_IOCTL, 94 | "Error opening IoTarget object - 0x%x\n", 95 | status); 96 | WdfObjectDelete(pDevice->busIoTarget); 97 | return status; 98 | } 99 | 100 | status = WdfIoTargetQueryForInterface(pDevice->busIoTarget, 101 | &GUID_CROSEC_INTERFACE_STANDARD, 102 | (PINTERFACE)&CrosEcInterface, 103 | sizeof(CrosEcInterface), 104 | 1, 105 | NULL); 106 | WdfIoTargetClose(pDevice->busIoTarget); 107 | pDevice->busIoTarget = NULL; 108 | if (!NT_SUCCESS(status)) { 109 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_PNP, 110 | "WdfFdoQueryForInterface failed 0x%x\n", status); 111 | return status; 112 | } 113 | 114 | pDevice->CrosEcBusContext = CrosEcInterface.InterfaceHeader.Context; 115 | pDevice->CrosEcCmdXferStatus = CrosEcInterface.CmdXferStatus; 116 | return status; 117 | } 118 | 119 | NTSTATUS 120 | OnPrepareHardware( 121 | _In_ WDFDEVICE FxDevice, 122 | _In_ WDFCMRESLIST FxResourcesRaw, 123 | _In_ WDFCMRESLIST FxResourcesTranslated 124 | ) 125 | /*++ 126 | 127 | Routine Description: 128 | 129 | This routine caches the SPB resource connection ID. 130 | 131 | Arguments: 132 | 133 | FxDevice - a handle to the framework device object 134 | FxResourcesRaw - list of translated hardware resources that 135 | the PnP manager has assigned to the device 136 | FxResourcesTranslated - list of raw hardware resources that 137 | the PnP manager has assigned to the device 138 | 139 | Return Value: 140 | 141 | Status 142 | 143 | --*/ 144 | { 145 | PCROSECCODEC_CONTEXT pDevice = GetDeviceContext(FxDevice); 146 | NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES; 147 | 148 | UNREFERENCED_PARAMETER(FxResourcesRaw); 149 | UNREFERENCED_PARAMETER(FxResourcesTranslated); 150 | 151 | status = ConnectToEc(FxDevice); 152 | if (!NT_SUCCESS(status)) { 153 | return status; 154 | } 155 | 156 | 157 | (*pDevice->CrosEcCmdXferStatus)(pDevice->CrosEcBusContext, NULL); 158 | 159 | return status; 160 | } 161 | 162 | NTSTATUS 163 | OnReleaseHardware( 164 | _In_ WDFDEVICE FxDevice, 165 | _In_ WDFCMRESLIST FxResourcesTranslated 166 | ) 167 | /*++ 168 | 169 | Routine Description: 170 | 171 | Arguments: 172 | 173 | FxDevice - a handle to the framework device object 174 | FxResourcesTranslated - list of raw hardware resources that 175 | the PnP manager has assigned to the device 176 | 177 | Return Value: 178 | 179 | Status 180 | 181 | --*/ 182 | { 183 | NTSTATUS status = STATUS_SUCCESS; 184 | 185 | UNREFERENCED_PARAMETER(FxResourcesTranslated); 186 | 187 | return status; 188 | } 189 | 190 | static NTSTATUS send_ec_command( 191 | _In_ PCROSECCODEC_CONTEXT pDevice, 192 | UINT32 cmd, 193 | UINT8* out, 194 | size_t outSize, 195 | UINT8* in, 196 | size_t inSize) 197 | { 198 | struct cros_ec_command* msg = ExAllocatePoolWithTag(NonPagedPool, sizeof(struct cros_ec_command) + max(outSize, inSize), CROSECCODEC_POOL_TAG); 199 | if (!msg) { 200 | return STATUS_NO_MEMORY; 201 | } 202 | msg->version = 0; 203 | msg->command = cmd; 204 | msg->outsize = outSize; 205 | msg->insize = inSize; 206 | 207 | if (outSize) 208 | memcpy(msg->data, out, outSize); 209 | 210 | NTSTATUS status = (*pDevice->CrosEcCmdXferStatus)(pDevice->CrosEcBusContext, msg); 211 | if (!NT_SUCCESS(status)) { 212 | goto exit; 213 | } 214 | 215 | if (in && inSize) { 216 | memcpy(in, msg->data, inSize); 217 | } 218 | 219 | exit: 220 | ExFreePoolWithTag(msg, CROSECCODEC_POOL_TAG); 221 | return status; 222 | } 223 | 224 | VOID 225 | CrosEcBootWorkItem( 226 | IN WDFWORKITEM WorkItem 227 | ) 228 | { 229 | WDFDEVICE Device = (WDFDEVICE)WdfWorkItemGetParentObject(WorkItem); 230 | PCROSECCODEC_CONTEXT pDevice = GetDeviceContext(Device); 231 | 232 | struct ec_param_ec_codec_i2s_rx i2sRxCmd; 233 | 234 | RtlZeroMemory(&i2sRxCmd, sizeof(i2sRxCmd)); 235 | i2sRxCmd.cmd = EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH; 236 | i2sRxCmd.set_sample_depth_param.depth = EC_CODEC_I2S_RX_SAMPLE_DEPTH_16; 237 | NTSTATUS status = send_ec_command(pDevice, EC_CMD_EC_CODEC_I2S_RX, (UINT8*)&i2sRxCmd, sizeof(i2sRxCmd), NULL, 0); 238 | if (!NT_SUCCESS(status)) { 239 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "Failed set set i2s sample depth\n"); 240 | goto exit; 241 | } 242 | 243 | RtlZeroMemory(&i2sRxCmd, sizeof(i2sRxCmd)); 244 | i2sRxCmd.cmd = EC_CODEC_I2S_RX_SET_BCLK; 245 | i2sRxCmd.set_bclk_param.bclk = 48000 * 64; 246 | status = send_ec_command(pDevice, EC_CMD_EC_CODEC_I2S_RX, (UINT8*)&i2sRxCmd, sizeof(i2sRxCmd), NULL, 0); 247 | if (!NT_SUCCESS(status)) { 248 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "Failed set set i2s bclk\n"); 249 | goto exit; 250 | } 251 | 252 | RtlZeroMemory(&i2sRxCmd, sizeof(i2sRxCmd)); 253 | i2sRxCmd.cmd = EC_CODEC_I2S_RX_SET_DAIFMT; 254 | i2sRxCmd.set_daifmt_param.daifmt = EC_CODEC_I2S_RX_DAIFMT_I2S; 255 | status = send_ec_command(pDevice, EC_CMD_EC_CODEC_I2S_RX, (UINT8*)&i2sRxCmd, sizeof(i2sRxCmd), NULL, 0); 256 | if (!NT_SUCCESS(status)) { 257 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "Failed set set i2s DAI fmt\n"); 258 | goto exit; 259 | } 260 | 261 | RtlZeroMemory(&i2sRxCmd, sizeof(i2sRxCmd)); 262 | i2sRxCmd.cmd = EC_CODEC_I2S_RX_ENABLE; 263 | status = send_ec_command(pDevice, EC_CMD_EC_CODEC_I2S_RX, (UINT8*)&i2sRxCmd, sizeof(i2sRxCmd), NULL, 0); 264 | if (!NT_SUCCESS(status)) { 265 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "Failed set set i2s enable\n"); 266 | goto exit; 267 | } 268 | 269 | exit: 270 | WdfObjectDelete(WorkItem); 271 | } 272 | 273 | void CrosEcCodecBootTimer(_In_ WDFTIMER hTimer) { 274 | WDFDEVICE Device = (WDFDEVICE)WdfTimerGetParentObject(hTimer); 275 | 276 | WDF_OBJECT_ATTRIBUTES attributes; 277 | WDF_WORKITEM_CONFIG workitemConfig; 278 | WDFWORKITEM hWorkItem; 279 | 280 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 281 | WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attributes, CROSECCODEC_CONTEXT); 282 | attributes.ParentObject = Device; 283 | WDF_WORKITEM_CONFIG_INIT(&workitemConfig, CrosEcBootWorkItem); 284 | 285 | WdfWorkItemCreate(&workitemConfig, 286 | &attributes, 287 | &hWorkItem); 288 | 289 | WdfWorkItemEnqueue(hWorkItem); 290 | WdfTimerStop(hTimer, FALSE); 291 | } 292 | 293 | NTSTATUS 294 | OnD0Entry( 295 | _In_ WDFDEVICE FxDevice, 296 | _In_ WDF_POWER_DEVICE_STATE FxPreviousState 297 | ) 298 | /*++ 299 | 300 | Routine Description: 301 | 302 | This routine allocates objects needed by the driver. 303 | 304 | Arguments: 305 | 306 | FxDevice - a handle to the framework device object 307 | FxPreviousState - previous power state 308 | 309 | Return Value: 310 | 311 | Status 312 | 313 | --*/ 314 | { 315 | PCROSECCODEC_CONTEXT pDevice = GetDeviceContext(FxDevice); 316 | UNREFERENCED_PARAMETER(FxPreviousState); 317 | NTSTATUS status = STATUS_SUCCESS; 318 | 319 | struct ec_param_ec_codec_i2s_rx i2sRxCmd; 320 | struct ec_response_ec_codec_dmic_get_max_gain dmicGain; 321 | 322 | RtlZeroMemory(&i2sRxCmd, sizeof(i2sRxCmd)); 323 | i2sRxCmd.cmd = EC_CODEC_I2S_RX_RESET; 324 | status = send_ec_command(pDevice, EC_CMD_EC_CODEC_I2S_RX, (UINT8*)&i2sRxCmd, sizeof(i2sRxCmd), NULL, 0); 325 | if (!NT_SUCCESS(status)) { 326 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "Failed set set i2s reset\n"); 327 | return status; 328 | } 329 | 330 | { 331 | struct ec_param_ec_codec_dmic dmicCmd; 332 | RtlZeroMemory(&dmicCmd, sizeof(dmicCmd)); 333 | dmicCmd.cmd = EC_CODEC_DMIC_GET_MAX_GAIN; 334 | 335 | status = send_ec_command(pDevice, EC_CMD_EC_CODEC_DMIC, (UINT8*)&dmicCmd, sizeof(dmicCmd), (UINT8*)&dmicGain, sizeof(dmicGain)); 336 | if (!NT_SUCCESS(status)) { 337 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "Failed to get max gain\n"); 338 | return status; 339 | } 340 | 341 | RtlZeroMemory(&dmicCmd, sizeof(dmicCmd)); 342 | dmicCmd.cmd = EC_CODEC_DMIC_SET_GAIN_IDX; 343 | dmicCmd.set_gain_idx_param.channel = EC_CODEC_DMIC_CHANNEL_0; 344 | dmicCmd.set_gain_idx_param.gain = dmicGain.max_gain; 345 | status = send_ec_command(pDevice, EC_CMD_EC_CODEC_DMIC, (UINT8*)&dmicCmd, sizeof(dmicCmd), NULL, 0); 346 | if (!NT_SUCCESS(status)) { 347 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "Failed set gain on channel 0\n"); 348 | return status; 349 | } 350 | 351 | RtlZeroMemory(&dmicCmd, sizeof(dmicCmd)); 352 | dmicCmd.cmd = EC_CODEC_DMIC_SET_GAIN_IDX; 353 | dmicCmd.set_gain_idx_param.channel = EC_CODEC_DMIC_CHANNEL_1; 354 | dmicCmd.set_gain_idx_param.gain = dmicGain.max_gain; 355 | status = send_ec_command(pDevice, EC_CMD_EC_CODEC_DMIC, (UINT8*)&dmicCmd, sizeof(dmicCmd), NULL, 0); 356 | if (!NT_SUCCESS(status)) { 357 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_PNP, "Failed set gain on channel 1\n"); 358 | return status; 359 | } 360 | } 361 | 362 | WDF_TIMER_CONFIG timerConfig; 363 | WDFTIMER hTimer; 364 | WDF_OBJECT_ATTRIBUTES attributes; 365 | 366 | WDF_TIMER_CONFIG_INIT(&timerConfig, CrosEcCodecBootTimer); 367 | 368 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 369 | attributes.ParentObject = pDevice->FxDevice; 370 | status = WdfTimerCreate(&timerConfig, &attributes, &hTimer); 371 | 372 | WdfTimerStart(hTimer, WDF_REL_TIMEOUT_IN_MS(2000)); 373 | 374 | return status; 375 | } 376 | 377 | NTSTATUS 378 | OnD0Exit( 379 | _In_ WDFDEVICE FxDevice, 380 | _In_ WDF_POWER_DEVICE_STATE FxTargetState 381 | ) 382 | /*++ 383 | 384 | Routine Description: 385 | 386 | This routine destroys objects needed by the driver. 387 | 388 | Arguments: 389 | 390 | FxDevice - a handle to the framework device object 391 | FxTargetState - target power state 392 | 393 | Return Value: 394 | 395 | Status 396 | 397 | --*/ 398 | { 399 | UNREFERENCED_PARAMETER(FxTargetState); 400 | 401 | NTSTATUS status = STATUS_SUCCESS; 402 | 403 | return status; 404 | } 405 | 406 | NTSTATUS 407 | CrosEcCodecEvtDeviceAdd( 408 | IN WDFDRIVER Driver, 409 | IN PWDFDEVICE_INIT DeviceInit 410 | ) 411 | { 412 | NTSTATUS status = STATUS_SUCCESS; 413 | WDF_OBJECT_ATTRIBUTES attributes; 414 | WDFDEVICE device; 415 | PCROSECCODEC_CONTEXT devContext; 416 | 417 | UNREFERENCED_PARAMETER(Driver); 418 | 419 | PAGED_CODE(); 420 | 421 | CrosEcCodecPrint(DEBUG_LEVEL_INFO, DBG_PNP, 422 | "CrosEcCodecEvtDeviceAdd called\n"); 423 | 424 | { 425 | WDF_PNPPOWER_EVENT_CALLBACKS pnpCallbacks; 426 | WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpCallbacks); 427 | 428 | pnpCallbacks.EvtDevicePrepareHardware = OnPrepareHardware; 429 | pnpCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware; 430 | pnpCallbacks.EvtDeviceD0Entry = OnD0Entry; 431 | pnpCallbacks.EvtDeviceD0Exit = OnD0Exit; 432 | 433 | WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpCallbacks); 434 | } 435 | 436 | // 437 | // Setup the device context 438 | // 439 | 440 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CROSECCODEC_CONTEXT); 441 | 442 | // 443 | // Create a framework device object.This call will in turn create 444 | // a WDM device object, attach to the lower stack, and set the 445 | // appropriate flags and attributes. 446 | // 447 | 448 | status = WdfDeviceCreate(&DeviceInit, &attributes, &device); 449 | 450 | if (!NT_SUCCESS(status)) 451 | { 452 | CrosEcCodecPrint(DEBUG_LEVEL_ERROR, DBG_PNP, 453 | "WdfDeviceCreate failed with status code 0x%x\n", status); 454 | 455 | return status; 456 | } 457 | 458 | devContext = GetDeviceContext(device); 459 | 460 | devContext->FxDevice = device; 461 | 462 | return status; 463 | } --------------------------------------------------------------------------------