2 Copyright (C) 2017-2018, The AROS Development Team. All rights reserved.
7 #include <aros/debug.h>
10 #include <exec/types.h>
12 #include <proto/exec.h>
13 #include <proto/oop.h>
15 #include <aros/symbolsets.h>
16 #include <hidd/hidd.h>
17 #include <hidd/system.h>
21 #include "acpibutton_intern.h"
23 #include LC_LIBDEFS_FILE
25 AROS_UFH3(IPTR
, ACPIButton_PowerEventHandle
,
26 AROS_UFHA(struct Hook
*, hook
, A0
),
27 AROS_UFHA(APTR
, object
, A2
),
28 AROS_UFHA(APTR
, message
, A1
)
33 struct Task
*sigTask
= NULL
;
37 // ACPI_HANDLE device = (ACPI_HANDLE)message;
39 D(bug("[HWACPIButton] %s()\n", __func__
));
41 cl
= OOP_OCLASS(object
);
42 OOP_GetAttr(object
, aHW_ACPIButton_ServiceTask
, (IPTR
*)&sigTask
);
43 OOP_GetAttr(object
, aHW_ACPIButton_ServiceSigPower
, &powerSig
);
47 D(bug("[HWACPIButton] %s: Signalling service task to handle Power Button event..\n", __func__
));
48 Signal(sigTask
, (1 << powerSig
));
56 AROS_UFH3(IPTR
, ACPIButton_SleepEventHandle
,
57 AROS_UFHA(struct Hook
*, hook
, A0
),
58 AROS_UFHA(APTR
, object
, A2
),
59 AROS_UFHA(APTR
, message
, A1
)
64 // ACPI_HANDLE device = (ACPI_HANDLE)message;
67 bug("[HWACPIButton] %s()\n", __func__
);
68 bug("[HWACPIButton] %s: Unhandled\n", __func__
);
76 AROS_UFH3(IPTR
, ACPIButton_LidEventHandle
,
77 AROS_UFHA(struct Hook
*, hook
, A0
),
78 AROS_UFHA(APTR
, object
, A2
),
79 AROS_UFHA(APTR
, message
, A1
)
84 // ACPI_HANDLE device = (ACPI_HANDLE)message;
87 bug("[HWACPIButton] %s()\n", __func__
);
88 bug("[HWACPIButton] %s: Unhandled\n", __func__
);
96 BOOL
ACPIButton_MatchDeviceID(ACPI_DEVICE_INFO
*acpiDevInfo
, char *deviceID
)
98 ACPI_PNP_DEVICE_ID_LIST
*cIdList
;
99 ACPI_PNP_DEVICE_ID
*hwId
;
102 hwId
= AcpiGetInfoHardwareId(acpiDevInfo
);
103 if (hwId
&& !(strcmp(hwId
->String
, deviceID
)))
105 cIdList
= AcpiGetInfoCompatIdList(acpiDevInfo
);
107 for (cmptid
= 0; cmptid
< cIdList
->Count
; cmptid
++) {
108 if (!(strcmp(cIdList
->Ids
[cmptid
].String
, deviceID
)))
117 static ACPI_STATUS
ACPIButton_DeviceQuery(ACPI_HANDLE handle
,
122 struct acpibuttonclass_staticdata
*_csd
= (struct acpibuttonclass_staticdata
*)context
;
123 ACPI_DEVICE_INFO
*acpiDevInfo
= NULL
;
124 ACPI_STATUS acpiStatus
;
126 D(bug("[HWACPIButton] %s(0x%p)\n", __func__
, handle
));
128 acpiStatus
= AcpiGetObjectInfo(handle
, &acpiDevInfo
);
129 if (ACPI_FAILURE(acpiStatus
)) {
131 FreeVec(acpiDevInfo
);
136 if (ACPIButton_MatchDeviceID(acpiDevInfo
, "PNP0C0C"))
138 D(bug("[HWACPIButton] %s: Power Button Device Found\n", __func__
));
139 if ((!_csd
->powerButtonObj
) && (!_csd
->acpiPowerBHandle
))
141 _csd
->acpiPowerBHandle
= handle
;
142 _csd
->acpiPowerBType
= vHW_ACPIButton_Power
;
145 else if (ACPIButton_MatchDeviceID(acpiDevInfo
, "ACPI_FPB"))
147 D(bug("[HWACPIButton] %s: Fixed Power Button Device Found\n", __func__
));
148 if ((!_csd
->powerButtonObj
) && (!_csd
->acpiPowerBHandle
))
150 _csd
->acpiPowerBHandle
= handle
;
151 _csd
->acpiPowerBType
= vHW_ACPIButton_PowerF
;
154 else if (ACPIButton_MatchDeviceID(acpiDevInfo
, "PNP0C0E"))
156 D(bug("[HWACPIButton] %s: Sleep Button Device Found\n", __func__
));
157 if ((!_csd
->sleepButtonObj
) && (!_csd
->acpiSleepBHandle
))
159 _csd
->acpiSleepBHandle
= handle
;
160 _csd
->acpiSleepBType
= vHW_ACPIButton_Sleep
;
163 else if (ACPIButton_MatchDeviceID(acpiDevInfo
, "ACPI_FSB"))
165 D(bug("[HWACPIButton] %s: Fixed Sleep Button Device Found\n", __func__
));
166 if ((!_csd
->sleepButtonObj
) && (!_csd
->acpiSleepBHandle
))
168 _csd
->acpiSleepBHandle
= handle
;
169 _csd
->acpiSleepBType
= vHW_ACPIButton_SleepF
;
172 else if (ACPIButton_MatchDeviceID(acpiDevInfo
, "PNP0C0D"))
174 D(bug("[HWACPIButton] %s: Lid Button Device Found\n", __func__
));
175 if ((!_csd
->lidButtonObj
) && (!_csd
->acpibLidBHandle
))
177 _csd
->acpibLidBHandle
= handle
;
181 FreeVec(acpiDevInfo
);
186 static int ACPIButton_Init(LIBBASETYPEPTR LIBBASE
)
188 struct acpibuttonclass_staticdata
*_csd
= &LIBBASE
->hsi_csd
;
192 __unused ACPI_STATUS acpiStatus
;
194 D(bug("[HWACPIButton] %s()\n", __func__
));
195 D(bug("[HWACPIButton] %s: OOPBase @ 0x%p\n", __func__
, OOPBase
));
197 _csd
->cs_ACPICABase
= OpenLibrary("acpica.library", 0);
198 if (!_csd
->cs_ACPICABase
)
201 _csd
->cs_UtilityBase
= OpenLibrary("utility.library", 36);
202 if (!_csd
->cs_UtilityBase
)
204 CloseLibrary(_csd
->cs_ACPICABase
);
208 root
= OOP_NewObject(NULL
, CLID_Hidd_System
, NULL
);
210 root
= OOP_NewObject(NULL
, CLID_HW_Root
, NULL
);
212 _csd
->hwAB
= OOP_ObtainAttrBase(IID_HW
);
213 _csd
->hiddAB
= OOP_ObtainAttrBase(IID_Hidd
);
214 _csd
->hwACPIButtonAB
= OOP_ObtainAttrBase(IID_HW_ACPIButton
);
217 struct TagItem instanceTags
[] =
219 { _csd
->hwACPIButtonAB
+ aoHW_ACPIButton_Type
, 0},
220 { _csd
->hwACPIButtonAB
+ aoHW_ACPIButton_Handle
, 0},
221 { _csd
->hwACPIButtonAB
+ aoHW_ACPIButton_Hook
, 0},
224 ACPI_TABLE_FADT
*fadt
;
225 struct Hook
*buttonHook
;
227 /* check for fixed feature buttons .. */
228 if (AcpiGetTable(ACPI_SIG_FADT
, 1, (ACPI_TABLE_HEADER
**)&fadt
) == AE_OK
)
230 if ((!(fadt
->Flags
& ACPI_FADT_POWER_BUTTON
)) && (!_csd
->powerButtonObj
))
232 D(bug("[HWACPIButton] %s: Fixed Power-Button Enabled in FADT\n", __func__
));
233 AcpiEnableEvent(ACPI_EVENT_POWER_BUTTON
, 0);
234 AcpiClearEvent(ACPI_EVENT_POWER_BUTTON
);
235 _csd
->acpiPowerBType
= vHW_ACPIButton_PowerF
;
236 instanceTags
[0].ti_Data
= (IPTR
)_csd
->acpiPowerBType
;
237 instanceTags
[1].ti_Data
= 0;
239 buttonHook
= AllocMem(sizeof(struct Hook
), MEMF_CLEAR
);
240 buttonHook
->h_Entry
= (HOOKFUNC
)ACPIButton_PowerEventHandle
;
241 buttonHook
->h_Data
= 0;
242 instanceTags
[2].ti_Data
= (IPTR
)buttonHook
;
244 if (HW_AddDriver(root
, _csd
->oopclass
, instanceTags
))
246 D(bug("[HWACPIButton] %s: Fixed Power-Button initialised\n", __func__
));
250 FreeMem(buttonHook
, sizeof(struct Hook
));
252 if ((!(fadt
->Flags
& ACPI_FADT_SLEEP_BUTTON
)) && (!_csd
->sleepButtonObj
))
254 D(bug("[HWACPIButton] %s: Fixed Sleep-Button Enabled in FADT\n", __func__
));
255 AcpiEnableEvent(ACPI_EVENT_SLEEP_BUTTON
, 0);
256 AcpiClearEvent(ACPI_EVENT_SLEEP_BUTTON
);
257 _csd
->acpiSleepBType
= vHW_ACPIButton_SleepF
;
258 instanceTags
[0].ti_Data
= (IPTR
)_csd
->acpiSleepBType
;
259 instanceTags
[1].ti_Data
= 0;
261 buttonHook
= AllocMem(sizeof(struct Hook
), MEMF_CLEAR
);
262 buttonHook
->h_Entry
= (HOOKFUNC
)ACPIButton_SleepEventHandle
;
263 buttonHook
->h_Data
= 0;
264 instanceTags
[2].ti_Data
= (IPTR
)buttonHook
;
266 if (HW_AddDriver(root
, _csd
->oopclass
, instanceTags
))
268 D(bug("[HWACPIButton] %s: Fixed Sleep-Button initialised\n", __func__
));
272 FreeMem(buttonHook
, sizeof(struct Hook
));
276 /* check for button devices .. */
277 acpiStatus
= AcpiWalkNamespace(ACPI_TYPE_DEVICE
, ACPI_ROOT_OBJECT
, INT_MAX
, ACPIButton_DeviceQuery
, NULL
, _csd
, NULL
);
278 if (acpiStatus
== AE_OK
)
280 if ((_csd
->acpiPowerBHandle
!= NULL
) && (!_csd
->powerButtonObj
))
282 instanceTags
[0].ti_Data
= (IPTR
)_csd
->acpiPowerBType
;
283 instanceTags
[1].ti_Data
= (IPTR
)_csd
->acpiPowerBHandle
;
285 buttonHook
= AllocMem(sizeof(struct Hook
), MEMF_CLEAR
);
286 buttonHook
->h_Entry
= (HOOKFUNC
)ACPIButton_PowerEventHandle
;
287 buttonHook
->h_Data
= 0;
288 instanceTags
[2].ti_Data
= (IPTR
)buttonHook
;
290 if (HW_AddDriver(root
, _csd
->oopclass
, instanceTags
))
292 D(bug("[HWACPIButton] %s: Power-Button initialised\n", __func__
));
296 FreeMem(buttonHook
, sizeof(struct Hook
));
299 if ((_csd
->acpiSleepBHandle
!= NULL
) && (!_csd
->sleepButtonObj
))
301 instanceTags
[0].ti_Data
= (IPTR
)_csd
->acpiSleepBType
;
302 instanceTags
[1].ti_Data
= (IPTR
)_csd
->acpiSleepBHandle
;
304 buttonHook
= AllocMem(sizeof(struct Hook
), MEMF_CLEAR
);
305 buttonHook
->h_Entry
= (HOOKFUNC
)ACPIButton_SleepEventHandle
;
306 buttonHook
->h_Data
= 0;
307 instanceTags
[2].ti_Data
= (IPTR
)buttonHook
;
309 if (HW_AddDriver(root
, _csd
->oopclass
, instanceTags
))
311 D(bug("[HWACPIButton] %s: Sleep-Button initialised\n", __func__
));
315 FreeMem(buttonHook
, sizeof(struct Hook
));
318 if ((_csd
->acpibLidBHandle
!= NULL
) && (!_csd
->lidButtonObj
))
320 instanceTags
[0].ti_Data
= vHW_ACPIButton_Lid
;
321 instanceTags
[1].ti_Data
= (IPTR
)_csd
->acpibLidBHandle
;
323 buttonHook
= AllocMem(sizeof(struct Hook
), MEMF_CLEAR
);
324 buttonHook
->h_Entry
= (HOOKFUNC
)ACPIButton_LidEventHandle
;
325 buttonHook
->h_Data
= 0;
326 instanceTags
[2].ti_Data
= (IPTR
)buttonHook
;
328 if (HW_AddDriver(root
, _csd
->oopclass
, instanceTags
))
330 D(bug("[HWACPIButton] %s: Lid-Button initialised\n", __func__
));
334 FreeMem(buttonHook
, sizeof(struct Hook
));
343 CloseLibrary(_csd
->cs_UtilityBase
);
344 CloseLibrary(_csd
->cs_ACPICABase
);
347 D(bug("[HWACPIButton] %s: Finished\n", __func__
));
352 static int ACPIButton_Expunge(LIBBASETYPEPTR LIBBASE
)
354 D(struct acpibuttonclass_staticdata
*_csd
= &LIBBASE
->hsi_csd
;)
357 bug("[HWACPIButton] %s()\n", __func__
);
358 bug("[HWACPIButton] %s: csd @ %p\n", __func__
, _csd
);
364 ADD2INITLIB(ACPIButton_Init
, -2)
365 ADD2EXPUNGELIB(ACPIButton_Expunge
, -2)