LM3642 Initial Commit : Synchronous Boost Single LED Flash Driver
[windows-iot-driver/drivers.git] / LM3642 / TxnwLedLM3642 / Driver.c
1 /*++\r
2 Copyright (c) Texas Instruments Inc. All Rights Reserved.\r
3 Sample code for LED FLASH LM3642.\r
4 \r
5 The MIT License (MIT)\r
6 \r
7 Permission is hereby granted, free of charge, to any person obtaining a copy\r
8 of this software and associated documentation files (the "Software"), to deal\r
9 in the Software without restriction, including without limitation the rights\r
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
11 copies of the Software, and to permit persons to whom the Software is\r
12 furnished to do so, subject to the following conditions:\r
13 \r
14 The above copyright notice and this permission notice shall be included in\r
15 all copies or substantial portions of the Software.\r
16 \r
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
23 THE SOFTWARE.\r
24 \r
25 Module Name:\r
26 \r
27 driver.c\r
28 \r
29 Abstract:\r
30 \r
31 This file contains the driver entry points and callbacks.\r
32 \r
33 Environment:\r
34 \r
35 Kernel-mode Driver Framework\r
36 \r
37 --*/\r
38 \r
39 #include "driver.h"\r
40 #include "driver.tmh"\r
41 #include "Public.h"\r
42 \r
43 #ifdef ALLOC_PRAGMA\r
44 #pragma alloc_text (INIT, DriverEntry)\r
45 #pragma alloc_text (PAGE, TxnwLedLm3642EvtDeviceAdd)\r
46 #pragma alloc_text (PAGE, TxnwLedLm3642EvtDriverContextCleanup)\r
47 #endif\r
49 #define TXN_DEVICE_NAME L"TxnwLedLm3642"\r
50 \r
51 NTSTATUS\r
52 DriverEntry(\r
53         _In_ PDRIVER_OBJECT  DriverObject,\r
54         _In_ PUNICODE_STRING RegistryPath\r
55         )\r
56         /*++\r
57 \r
58         Routine Description:\r
59         DriverEntry initializes the driver and is the first routine called by the\r
60         system after the driver is loaded. DriverEntry specifies the other entry\r
61         points in the function driver, such as EvtDevice and DriverUnload.\r
62 \r
63         Parameters Description:\r
64 \r
65         DriverObject - represents the instance of the function driver that is loaded\r
66         into memory. DriverEntry must initialize members of DriverObject before it\r
67         returns to the caller. DriverObject is allocated by the system before the\r
68         driver is loaded, and it is released by the system after the system unloads\r
69         the function driver from memory.\r
70 \r
71         RegistryPath - represents the driver specific path in the Registry.\r
72         The function driver can use the path to store driver related data between\r
73         reboots. The path does not store hardware instance specific data.\r
74 \r
75         Return Value:\r
76 \r
77         STATUS_SUCCESS if successful,\r
78         STATUS_UNSUCCESSFUL otherwise.\r
79 \r
80         --*/\r
81 {\r
82         WDF_DRIVER_CONFIG config;\r
83         NTSTATUS status;\r
84         WDF_OBJECT_ATTRIBUTES attributes;\r
85 \r
86         //\r
87         // Initialize WPP Tracing\r
88         //\r
89         WPP_INIT_TRACING(DriverObject, RegistryPath);\r
90 \r
91 \r
92         //\r
93         // Register a cleanup callback so that we can call WPP_CLEANUP when\r
94         // the framework driver object is deleted during driver unload.\r
95         //\r
96         WDF_OBJECT_ATTRIBUTES_INIT(&attributes);\r
97         attributes.EvtCleanupCallback = TxnwLedLm3642EvtDriverContextCleanup;\r
98 \r
99         WDF_DRIVER_CONFIG_INIT(&config,\r
100                 TxnwLedLm3642EvtDeviceAdd\r
101                 );\r
102 \r
103         status = WdfDriverCreate(DriverObject,\r
104                 RegistryPath,\r
105                 &attributes,\r
106                 &config,\r
107                 WDF_NO_HANDLE\r
108                 );\r
109 \r
110         if (!NT_SUCCESS(status)) {\r
111                 WPP_CLEANUP(DriverObject);\r
112                 return status;\r
113         }\r
114 \r
115         return status;\r
116 }\r
117 \r
118 NTSTATUS\r
119 TxnwLedLm3642EvtDeviceAdd(\r
120         _In_    WDFDRIVER       Driver,\r
121         _Inout_ PWDFDEVICE_INIT DeviceInit\r
122         )\r
123         /*++\r
124         Routine Description:\r
125 \r
126         EvtDeviceAdd is called by the framework in response to AddDevice\r
127         call from the PnP manager. We create and initialize a device object to\r
128         represent a new instance of the device.\r
129 \r
130         Arguments:\r
131 \r
132         Driver - Handle to a framework driver object created in DriverEntry\r
133 \r
134         DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.\r
135 \r
136         Return Value:\r
137 \r
138         NTSTATUS\r
139 \r
140         --*/\r
141 {\r
142         WDF_OBJECT_ATTRIBUTES attributes;\r
143         PDEVICE_EXTENSION devContext;\r
144         WDFDEVICE fxDevice;\r
145         WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;\r
146         WDF_IO_QUEUE_CONFIG queueConfig;\r
147         NTSTATUS status;\r
148 \r
149 \r
150         UNREFERENCED_PARAMETER(Driver);\r
151 \r
152         PAGED_CODE();\r
153 \r
154         WdfDeviceInitSetPowerPolicyOwnership(DeviceInit, FALSE);\r
155         //\r
156         // This driver handles D0 Entry and Exit to power on and off the\r
157         // controller. It also handles prepare/release hardware so that it \r
158         // can acquire and free SPB resources needed to communicate with the  \r
159         // touch controller.\r
160         //\r
161         WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);\r
162 \r
163         pnpPowerCallbacks.EvtDeviceD0Entry = OnD0Entry;\r
164         pnpPowerCallbacks.EvtDeviceD0Exit = OnD0Exit;\r
165         pnpPowerCallbacks.EvtDevicePrepareHardware = OnPrepareHardware;\r
166         pnpPowerCallbacks.EvtDeviceReleaseHardware = OnReleaseHardware;\r
167 \r
168         WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);\r
169 \r
170         //\r
171         // Create a framework device object. This call will in turn create\r
172         // a WDM device object, attach to the lower stack, and set the\r
173         // appropriate flags and attributes.\r
174         //\r
175         WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_EXTENSION);\r
176 \r
177         status = WdfDeviceCreate(&DeviceInit, &attributes, &fxDevice);\r
178 \r
179         if (!NT_SUCCESS(status))\r
180         {\r
181                 goto exit;\r
182         }\r
183 \r
184         devContext = GetDeviceContext(fxDevice);\r
185         devContext->FxDevice = fxDevice;\r
186 \r
187         //\r
188         // Create a parallel dispatch queue to handle requests\r
189         //\r
190         WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(\r
191                 &queueConfig,\r
192                 WdfIoQueueDispatchSequential);\r
193 \r
194         queueConfig.EvtIoDeviceControl = OnDeviceControl;\r
195         queueConfig.PowerManaged = WdfFalse;\r
196 \r
197         status = WdfIoQueueCreate(\r
198                 fxDevice,\r
199                 &queueConfig,\r
200                 WDF_NO_OBJECT_ATTRIBUTES,\r
201                 &devContext->DefaultQueue);\r
202 \r
203         if (!NT_SUCCESS(status))\r
204         {\r
205                 goto exit;\r
206         }\r
207 \r
208         //\r
209         // Register a manual I/O queue for Read Requests. This queue will be used \r
210         // for storing read-requests until data is available to complete them.\r
211         //\r
212         WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);\r
213 \r
214         queueConfig.PowerManaged = WdfFalse;\r
215 \r
216         status = WdfIoQueueCreate(\r
217                 fxDevice,\r
218                 &queueConfig,\r
219                 WDF_NO_OBJECT_ATTRIBUTES,\r
220                 &devContext->PingPongQueue);\r
221 \r
222         if (!NT_SUCCESS(status))\r
223         {\r
224                 goto exit;\r
225         }\r
226         //\r
227         // Register one last manual I/O queue for parking idle power\r
228         // requests. This queue stores idle requests until they're cancelled,\r
229         // and could be used to complete a wait/wake request.\r
230         //\r
231 \r
232         WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchManual);\r
233 \r
234         queueConfig.PowerManaged = WdfFalse;\r
235 \r
236         status = WdfIoQueueCreate(\r
237                 fxDevice,\r
238                 &queueConfig,\r
239                 WDF_NO_OBJECT_ATTRIBUTES,\r
240                 &devContext->IdleQueue\r
241                 );\r
242 \r
243         if (!NT_SUCCESS(status))\r
244         {\r
245                 goto exit;\r
246         }\r
247 \r
248         DECLARE_CONST_UNICODE_STRING(symbolicLink, L"\\DosDevices\\" LM3642_DEVICE_NAME);\r
249         status = WdfDeviceCreateSymbolicLink(fxDevice, &symbolicLink);\r
250 \r
251 exit:\r
252         return status;\r
253 }\r
254 \r
255 VOID\r
256 TxnwLedLm3642EvtDriverContextCleanup(\r
257         _In_ WDFOBJECT DriverObject\r
258         )\r
259         /*++\r
260         Routine Description:\r
261 \r
262         Free all the resources allocated in DriverEntry.\r
263 \r
264         Arguments:\r
265 \r
266         DriverObject - handle to a WDF Driver object.\r
267 \r
268         Return Value:\r
269 \r
270         VOID.\r
271 \r
272         --*/\r
273 {\r
274         UNREFERENCED_PARAMETER(DriverObject);\r
275 \r
276         PAGED_CODE();\r
277 \r
278         WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject));\r
279 }\r