2 * Copyright 2009-2015, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, axeld@pinc-software.de
7 * Clemens Zeidler, haiku@clemens-zeidler.de
11 #include "ACPIDriverInterface.h"
18 #include <Directory.h>
23 static const char* kDriverDir
= "/dev/power";
26 RateBuffer::RateBuffer()
29 fSize(kRateBufferSize
),
36 RateBuffer::AddRate(int32 rate
)
38 fRateBuffer
[fPosition
] = rate
;
40 if (fPosition
>= fSize
)
43 if (fCurrentSize
< fSize
)
49 RateBuffer::GetMeanRate()
52 for (int8 i
= 0; i
< fCurrentSize
; i
++) {
53 mean
+= fRateBuffer
[i
];
56 if (fCurrentSize
== 0)
59 return mean
/ fCurrentSize
;
66 Battery::Battery(int driverHandler
)
68 fDriverHandler(driverHandler
)
76 close(fDriverHandler
);
88 Battery::UpdateBatteryInfo()
90 acpi_battery_info info
;
91 if (ioctl(fDriverHandler
, GET_BATTERY_INFO
, &info
,
92 sizeof(acpi_battery_info
)) != 0)
95 if ((fExtendedBatteryInfo
.last_full_charge
> 0
96 && info
.capacity
> fExtendedBatteryInfo
.last_full_charge
)
106 Battery::GetBatteryInfoCached(battery_info
* info
)
108 info
->state
= fCachedInfo
.state
;
109 info
->current_rate
= fCachedInfo
.current_rate
;
110 info
->capacity
= fCachedInfo
.capacity
;
111 info
->full_capacity
= fExtendedBatteryInfo
.last_full_charge
;
112 if (info
->full_capacity
< 0)
113 info
->full_capacity
= fExtendedBatteryInfo
.design_capacity
;
115 fRateBuffer
.AddRate(fCachedInfo
.current_rate
);
116 if (fCachedInfo
.current_rate
> 0 && fRateBuffer
.GetMeanRate() != 0) {
117 info
->time_left
= 3600 * fCachedInfo
.capacity
118 / fRateBuffer
.GetMeanRate();
120 info
->time_left
= -1;
127 Battery::GetExtendedBatteryInfo(acpi_extended_battery_info
* info
)
129 if (ioctl(fDriverHandler
, GET_EXTENDED_BATTERY_INFO
, info
,
130 sizeof(acpi_extended_battery_info
)) != 0)
141 if (ioctl(fDriverHandler
, IDENTIFY_DEVICE
, &magicId
, sizeof(uint32
)) != 0) {
145 fInitStatus
= GetExtendedBatteryInfo(&fExtendedBatteryInfo
);
146 if (fInitStatus
!= B_OK
)
149 printf("ACPI driver found\n");
154 // #pragma mark - ACPIDriverInterface
157 ACPIDriverInterface::ACPIDriverInterface()
159 fInterfaceLocker("acpi interface")
164 ACPIDriverInterface::~ACPIDriverInterface()
166 for (int i
= 0; i
< fDriverList
.CountItems(); i
++)
167 delete fDriverList
.ItemAt(i
);
172 ACPIDriverInterface::Connect()
174 return _FindDrivers(kDriverDir
);
179 ACPIDriverInterface::GetBatteryInfo(int32 index
, battery_info
* info
)
181 BAutolock
autolock(fInterfaceLocker
);
182 if (index
< 0 || index
>= fDriverList
.CountItems())
185 return fDriverList
.ItemAt(index
)->GetBatteryInfoCached(info
);
190 ACPIDriverInterface::GetExtendedBatteryInfo(int32 index
,
191 acpi_extended_battery_info
* info
)
193 BAutolock
autolock(fInterfaceLocker
);
194 if (index
< 0 || index
>= fDriverList
.CountItems())
197 return fDriverList
.ItemAt(index
)->GetExtendedBatteryInfo(info
);
202 ACPIDriverInterface::GetBatteryCount()
204 return fDriverList
.CountItems();
209 ACPIDriverInterface::_UpdateBatteryInfo()
211 for (int i
= 0; i
< fDriverList
.CountItems(); i
++)
212 fDriverList
.ItemAt(i
)->UpdateBatteryInfo();
219 ACPIDriverInterface::_WatchPowerStatus()
221 const bigtime_t kUpdateInterval
= 2000000;
224 while (atomic_get(&fIsWatching
) > 0) {
225 _UpdateBatteryInfo();
226 Broadcast(kMsgUpdate
);
227 acquire_sem_etc(fWaitSem
, 1, B_RELATIVE_TIMEOUT
, kUpdateInterval
);
233 ACPIDriverInterface::_FindDrivers(const char* dirpath
)
235 BDirectory
dir(dirpath
);
238 status_t status
= B_ERROR
;
240 while (dir
.GetNextEntry(&entry
) == B_OK
) {
242 entry
.GetPath(&path
);
244 if (entry
.IsDirectory()) {
245 if (_FindDrivers(path
.Path()) == B_OK
)
248 int32 handler
= open(path
.Path(), O_RDWR
);
250 printf("try %s\n", path
.Path());
251 Battery
* battery
= new Battery(handler
);
252 if (battery
->InitCheck() == B_OK
253 && fDriverList
.AddItem(battery
)) {