BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / apps / powerstatus / ACPIDriverInterface.cpp
blob1036a9f2e2d03f67d98212cc4be790b9a1734e7a
1 /*
2 * Copyright 2009-2015, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 * Clemens Zeidler, haiku@clemens-zeidler.de
8 */
11 #include "ACPIDriverInterface.h"
13 #include <errno.h>
14 #include <stdio.h>
15 #include <string.h>
17 #include <Autolock.h>
18 #include <Directory.h>
19 #include <Entry.h>
20 #include <Path.h>
23 static const char* kDriverDir = "/dev/power";
26 RateBuffer::RateBuffer()
28 fPosition(0),
29 fSize(kRateBufferSize),
30 fCurrentSize(0)
35 void
36 RateBuffer::AddRate(int32 rate)
38 fRateBuffer[fPosition] = rate;
39 fPosition ++;
40 if (fPosition >= fSize)
41 fPosition = 0;
43 if (fCurrentSize < fSize)
44 fCurrentSize ++;
48 int32
49 RateBuffer::GetMeanRate()
51 int32 mean = 0;
52 for (int8 i = 0; i < fCurrentSize; i++) {
53 mean += fRateBuffer[i];
56 if (fCurrentSize == 0)
57 return -1;
59 return mean / fCurrentSize;
63 // #pragma mark -
66 Battery::Battery(int driverHandler)
68 fDriverHandler(driverHandler)
70 _Init();
74 Battery::~Battery()
76 close(fDriverHandler);
80 status_t
81 Battery::InitCheck()
83 return fInitStatus;
87 status_t
88 Battery::UpdateBatteryInfo()
90 acpi_battery_info info;
91 if (ioctl(fDriverHandler, GET_BATTERY_INFO, &info,
92 sizeof(acpi_battery_info)) != 0)
93 return errno;
95 if ((fExtendedBatteryInfo.last_full_charge > 0
96 && info.capacity > fExtendedBatteryInfo.last_full_charge)
97 || info.capacity < 0)
98 return B_BAD_DATA;
100 fCachedInfo = info;
101 return B_OK;
105 status_t
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();
119 } else
120 info->time_left = -1;
122 return B_OK;
126 status_t
127 Battery::GetExtendedBatteryInfo(acpi_extended_battery_info* info)
129 if (ioctl(fDriverHandler, GET_EXTENDED_BATTERY_INFO, info,
130 sizeof(acpi_extended_battery_info)) != 0)
131 return errno;
133 return B_OK;
137 void
138 Battery::_Init()
140 uint32 magicId = 0;
141 if (ioctl(fDriverHandler, IDENTIFY_DEVICE, &magicId, sizeof(uint32)) != 0) {
142 fInitStatus = errno;
143 return;
145 fInitStatus = GetExtendedBatteryInfo(&fExtendedBatteryInfo);
146 if (fInitStatus != B_OK)
147 return;
149 printf("ACPI driver found\n");
150 UpdateBatteryInfo();
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);
171 status_t
172 ACPIDriverInterface::Connect()
174 return _FindDrivers(kDriverDir);
178 status_t
179 ACPIDriverInterface::GetBatteryInfo(int32 index, battery_info* info)
181 BAutolock autolock(fInterfaceLocker);
182 if (index < 0 || index >= fDriverList.CountItems())
183 return B_ERROR;
185 return fDriverList.ItemAt(index)->GetBatteryInfoCached(info);
189 status_t
190 ACPIDriverInterface::GetExtendedBatteryInfo(int32 index,
191 acpi_extended_battery_info* info)
193 BAutolock autolock(fInterfaceLocker);
194 if (index < 0 || index >= fDriverList.CountItems())
195 return B_ERROR;
197 return fDriverList.ItemAt(index)->GetExtendedBatteryInfo(info);
201 int32
202 ACPIDriverInterface::GetBatteryCount()
204 return fDriverList.CountItems();
208 status_t
209 ACPIDriverInterface::_UpdateBatteryInfo()
211 for (int i = 0; i < fDriverList.CountItems(); i++)
212 fDriverList.ItemAt(i)->UpdateBatteryInfo();
214 return B_OK;
218 void
219 ACPIDriverInterface::_WatchPowerStatus()
221 const bigtime_t kUpdateInterval = 2000000;
222 // every two seconds
224 while (atomic_get(&fIsWatching) > 0) {
225 _UpdateBatteryInfo();
226 Broadcast(kMsgUpdate);
227 acquire_sem_etc(fWaitSem, 1, B_RELATIVE_TIMEOUT, kUpdateInterval);
232 status_t
233 ACPIDriverInterface::_FindDrivers(const char* dirpath)
235 BDirectory dir(dirpath);
236 BEntry entry;
238 status_t status = B_ERROR;
240 while (dir.GetNextEntry(&entry) == B_OK) {
241 BPath path;
242 entry.GetPath(&path);
244 if (entry.IsDirectory()) {
245 if (_FindDrivers(path.Path()) == B_OK)
246 return B_OK;
247 } else {
248 int32 handler = open(path.Path(), O_RDWR);
249 if (handler >= 0) {
250 printf("try %s\n", path.Path());
251 Battery* battery = new Battery(handler);
252 if (battery->InitCheck() == B_OK
253 && fDriverList.AddItem(battery)) {
254 status = B_OK;
255 } else
256 delete battery;
260 return status;