summaryrefslogtreecommitdiff
path: root/src/feature/battery.c
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2012-07-05 16:53:55 +0200
committerLars-Dominik Braun <lars@6xq.net>2012-07-05 16:53:55 +0200
commita5eb4ba1296c6279e5535bf3bcc1f1796707f6c6 (patch)
treef364b89467c2a38ce81e6ca0f2985d7a863c570e /src/feature/battery.c
downloadlshidpp-a5eb4ba1296c6279e5535bf3bcc1f1796707f6c6.tar.gz
lshidpp-a5eb4ba1296c6279e5535bf3bcc1f1796707f6c6.tar.bz2
lshidpp-a5eb4ba1296c6279e5535bf3bcc1f1796707f6c6.zip
Initial import
Diffstat (limited to 'src/feature/battery.c')
-rw-r--r--src/feature/battery.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/feature/battery.c b/src/feature/battery.c
new file mode 100644
index 0000000..7e2ed26
--- /dev/null
+++ b/src/feature/battery.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2012
+ * Lars-Dominik Braun <lars@6xq.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "battery.h"
+#include "usb.h"
+#include "device.h"
+
+typedef enum {
+ HIDPP_BATTERY_STATUS_DISCHARGING = 0,
+ HIDPP_BATTERY_STATUS_RECHARGING = 1,
+ HIDPP_BATTERY_STATUS_CHARGE_FINAL = 2,
+ HIDPP_BATTERY_STATUS_CHARGE_COMPLETE = 3,
+ HIDPP_BATTERY_STATUS_RECHARGING_SLOW = 4,
+ HIDPP_BATTERY_STATUS_INVALID_BATTERY = 5,
+ HIDPP_BATTERY_STATUS_THERMAL_ERROR = 6,
+ HIDPP_BATTERY_STATUS_CHARGE_ERROR = 7,
+} hidppBatteryStatus_t;
+
+typedef enum {
+ HIDPP_BATTERY_FLAGS_DISABLED = (1 << 0),
+ HIDPP_BATTERY_FLAGS_MILEAGE = (1 << 1),
+ HIDPP_BATTERY_FLAGS_RECHARGEABLE = (1 << 2),
+} hidppBatteryFlags_t;
+
+typedef struct {
+ uint8_t level, nextLevel, criticalLevel; /* in percent */
+ hidppBatteryStatus_t status;
+ uint8_t levelsCount;
+ hidppBatteryFlags_t flags;
+ uint16_t life;
+} hidppBattery_t;
+
+const char *hidppBatteryStatusToStr (const hidppBatteryStatus_t s) {
+ switch (s) {
+ case HIDPP_BATTERY_STATUS_DISCHARGING:
+ return "discharging";
+ break;
+
+ case HIDPP_BATTERY_STATUS_RECHARGING:
+ return "recharging";
+ break;
+
+ case HIDPP_BATTERY_STATUS_CHARGE_FINAL:
+ return "charge in final state";
+ break;
+
+ case HIDPP_BATTERY_STATUS_CHARGE_COMPLETE:
+ return "charge complete";
+ break;
+
+ case HIDPP_BATTERY_STATUS_RECHARGING_SLOW:
+ return "recharging below optimal speed";
+ break;
+
+ case HIDPP_BATTERY_STATUS_INVALID_BATTERY:
+ return "invalid battery";
+ break;
+
+ case HIDPP_BATTERY_STATUS_THERMAL_ERROR:
+ return "thermal error";
+ break;
+
+ case HIDPP_BATTERY_STATUS_CHARGE_ERROR:
+ return "charge error";
+ break;
+
+ default:
+ return "unkown";
+ break;
+ }
+}
+
+void hidppBatteryPrint (const void * const data) {
+ const hidppBattery_t * const b = data;
+
+ assert (b != NULL);
+
+ printf (" Battery:\n"
+ " Status: %s (%u)\n"
+ " Level: %u%%\n"
+ " Next level: %u%%\n"
+ " Critical level: %u%%\n"
+ " Number of levels: %u\n"
+ " Flags:%s%s%s (0x%x)\n"
+ " Life: %u\n",
+ hidppBatteryStatusToStr (b->status), b->status,
+ b->level, b->nextLevel, b->criticalLevel, b->levelsCount,
+ (b->flags & HIDPP_BATTERY_FLAGS_DISABLED) ? " disabled" : "",
+ (b->flags & HIDPP_BATTERY_FLAGS_MILEAGE) ? " mileage" : "",
+ (b->flags & HIDPP_BATTERY_FLAGS_RECHARGEABLE) ? " rechargeable" : "",
+ b->flags,
+ b->life);
+}
+
+void hidppBatteryGet (hidppDevice_t * const d, void ** const data) {
+ hidppBattery_t *b;
+ hidppPacket_t rp;
+
+ assert (d != NULL);
+
+ b = calloc (1, sizeof (*b));
+
+ hidppUsbRequest (d, HIDPP_FEATURE_BATTERY_STATUS, 0x0, NULL, 0, &rp);
+ b->level = rp.args[0];
+ b->nextLevel = rp.args[1];
+
+ hidppUsbRequest (d, HIDPP_FEATURE_BATTERY_STATUS, 0x1, NULL, 0, &rp);
+ b->levelsCount = rp.args[0];
+ b->flags = rp.args[1];
+ b->life = (rp.args[2] << 8) | rp.args[3];
+ b->criticalLevel = rp.args[4];
+
+ *data = b;
+}
+
+bool hidppBatteryAvailable (const hidppDevice_t * const d) {
+ uint8_t ret;
+ return hidppFeatureIdToIdx (d, HIDPP_FEATURE_BATTERY_STATUS, &ret);
+}
+
+hidppModule_t moduleBattery = {hidppBatteryAvailable, hidppBatteryGet,
+ hidppBatteryPrint};
+