summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Buren <braewoods+rb@braewoods.net>2021-03-10 04:09:46 -0600
committerJames Buren <braewoods+rb@braewoods.net>2021-03-10 04:09:46 -0600
commit0ba174789b45cd36fed61403898bbe5c2a01dcfb (patch)
tree63914375916ce9b9f8330d5f4aac4954d574a8d4
parent777f63d5292df98253bbb00db9362ddbe55b778e (diff)
downloadrockbox-0ba174789b45cd36fed61403898bbe5c2a01dcfb.tar.gz
rockbox-0ba174789b45cd36fed61403898bbe5c2a01dcfb.zip
usb_hid: switch Battery Strength to use feature reports
This means we will no longer send them routinely and instead rely on the HID driver to send them when the host requests it. This also moves the reporting out of the power management code where it probably did not belong in the first place. Change-Id: I9c8420e81897f1f6caaa55ffacc7525589f1ef75
-rw-r--r--firmware/export/powermgmt.h3
-rw-r--r--firmware/powermgmt.c21
-rw-r--r--firmware/usbstack/usb_hid.c86
3 files changed, 63 insertions, 47 deletions
diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h
index b7ca6772f3..235f5302f9 100644
--- a/firmware/export/powermgmt.h
+++ b/firmware/export/powermgmt.h
@@ -166,9 +166,6 @@ void set_poweroff_timeout(int timeout);
166void set_battery_capacity(int capacity); /* set local battery capacity value */ 166void set_battery_capacity(int capacity); /* set local battery capacity value */
167int get_battery_capacity(void); /* get local battery capacity value */ 167int get_battery_capacity(void); /* get local battery capacity value */
168void set_battery_type(int type); /* set local battery type */ 168void set_battery_type(int type); /* set local battery type */
169#ifdef USB_ENABLE_HID
170void set_battery_reporting(bool enable);
171#endif
172 169
173void set_sleeptimer_duration(int minutes); 170void set_sleeptimer_duration(int minutes);
174int get_sleep_timer(void); 171int get_sleep_timer(void);
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 969d6167da..6cac300cdf 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -48,9 +48,6 @@
48#if (CONFIG_PLATFORM & PLATFORM_HOSTED) 48#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
49#include <time.h> 49#include <time.h>
50#endif 50#endif
51#ifdef USB_ENABLE_HID
52#include "usbstack/usb_hid.h"
53#endif
54 51
55#if (defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(COWON_D2)) \ 52#if (defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(COWON_D2)) \
56 && !defined (SIMULATOR) 53 && !defined (SIMULATOR)
@@ -640,17 +637,6 @@ static void collect_power_history(void)
640 power_history[0] = power_hist_item(); 637 power_history[0] = power_hist_item();
641} 638}
642 639
643#ifdef USB_ENABLE_HID
644static bool battery_reporting = false;
645static int battery_report_percent = -1;
646
647void set_battery_reporting(bool enable)
648{
649 battery_reporting = enable;
650 battery_report_percent = -1;
651}
652#endif
653
654/* 640/*
655 * Monitor the presence of a charger and perform critical frequent steps 641 * Monitor the presence of a charger and perform critical frequent steps
656 * such as running the battery voltage filter. 642 * such as running the battery voltage filter.
@@ -764,13 +750,6 @@ static void power_thread(void)
764 next_power_hist += HZ*60; 750 next_power_hist += HZ*60;
765 collect_power_history(); 751 collect_power_history();
766 } 752 }
767
768#ifdef USB_ENABLE_HID
769 if (battery_reporting && battery_report_percent != battery_percent) {
770 battery_report_percent = battery_percent;
771 usb_hid_send(HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS, battery_report_percent);
772 }
773#endif
774 } 753 }
775} /* power_thread */ 754} /* power_thread */
776 755
diff --git a/firmware/usbstack/usb_hid.c b/firmware/usbstack/usb_hid.c
index 0b672e6452..5885b60e32 100644
--- a/firmware/usbstack/usb_hid.c
+++ b/firmware/usbstack/usb_hid.c
@@ -42,6 +42,7 @@
42/* HID main items (HID1_11.pdf, page 38) */ 42/* HID main items (HID1_11.pdf, page 38) */
43#define INPUT 0x80 43#define INPUT 0x80
44#define OUTPUT 0x90 44#define OUTPUT 0x90
45#define FEATURE 0xB0
45#define COLLECTION 0xA0 46#define COLLECTION 0xA0
46#define COLLECTION_PHYSICAL 0x00 47#define COLLECTION_PHYSICAL 0x00
47#define COLLECTION_APPLICATION 0x01 48#define COLLECTION_APPLICATION 0x01
@@ -90,6 +91,7 @@
90#define HID_BUF_SIZE_REPORT 160 91#define HID_BUF_SIZE_REPORT 160
91#define HID_NUM_BUFFERS 5 92#define HID_NUM_BUFFERS 5
92#define SET_REPORT_BUF_LEN 2 93#define SET_REPORT_BUF_LEN 2
94#define GET_REPORT_BUF_LEN 2
93 95
94#ifdef LOGF_ENABLE 96#ifdef LOGF_ENABLE
95 97
@@ -103,6 +105,8 @@
103#define HID_BUF_INC(i) do { (i) = ((i) + 1) % HID_NUM_BUFFERS; } while (0) 105#define HID_BUF_INC(i) do { (i) = ((i) + 1) % HID_NUM_BUFFERS; } while (0)
104#define PACK_VAL(dest, val) *(dest)++ = (val) & 0xff 106#define PACK_VAL(dest, val) *(dest)++ = (val) & 0xff
105 107
108#define REPORT_ID_BACKGROUND REPORT_ID_COUNT
109
106typedef enum 110typedef enum
107{ 111{
108 REPORT_ID_KEYBOARD = 1, 112 REPORT_ID_KEYBOARD = 1,
@@ -110,7 +114,6 @@ typedef enum
110#ifdef HAVE_USB_HID_MOUSE 114#ifdef HAVE_USB_HID_MOUSE
111 REPORT_ID_MOUSE, 115 REPORT_ID_MOUSE,
112#endif 116#endif
113 REPORT_ID_BACKGROUND,
114 REPORT_ID_COUNT, 117 REPORT_ID_COUNT,
115} report_id_t; 118} report_id_t;
116 119
@@ -452,15 +455,6 @@ static uint8_t buf_set_mouse(unsigned char *buf, int id)
452} 455}
453#endif /* HAVE_USB_HID_MOUSE */ 456#endif /* HAVE_USB_HID_MOUSE */
454 457
455#define BUF_LEN_BACKGROUND 1
456static uint8_t buf_set_background(unsigned char *buf, int id)
457{
458 memset(buf, 0, BUF_LEN_BACKGROUND);
459 buf[0] = (uint8_t)id;
460
461 return BUF_LEN_BACKGROUND;
462}
463
464static size_t descriptor_report_get(unsigned char *dest) 458static size_t descriptor_report_get(unsigned char *dest)
465{ 459{
466 unsigned char *report = dest; 460 unsigned char *report = dest;
@@ -562,22 +556,25 @@ static size_t descriptor_report_get(unsigned char *dest)
562 PACK_VAL(report, END_COLLECTION); 556 PACK_VAL(report, END_COLLECTION);
563#endif /* HAVE_USB_HID_MOUSE */ 557#endif /* HAVE_USB_HID_MOUSE */
564 558
565 /* Background controls */ 559 /* Background reports */
566 usb_hid_report = &usb_hid_reports[REPORT_ID_BACKGROUND];
567 usb_hid_report->usage_page = HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS;
568 usb_hid_report->buf_set = buf_set_background;
569 usb_hid_report->is_key_released = 0;
570
571 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS); 560 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS);
572 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_BACKGROUND_CONTROLS); 561 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_BACKGROUND_CONTROLS);
573 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION); 562 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
574 pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_BACKGROUND); 563 pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_BACKGROUND);
564 /* Padding */
565 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_UNDEFINED);
566 pack_parameter(&report, 0, 1, LOGICAL_MINIMUM, 0);
567 pack_parameter(&report, 0, 1, LOGICAL_MAXIMUM, 255);
568 pack_parameter(&report, 0, 1, REPORT_SIZE, 8);
569 pack_parameter(&report, 0, 1, REPORT_COUNT, 1);
570 pack_parameter(&report, 0, 1, FEATURE, MAIN_ITEM_CONSTANT);
571 /* Battery percentage */
575 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_BATTERY_STRENGTH); 572 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DEVICE_BATTERY_STRENGTH);
576 pack_parameter(&report, 0, 1, LOGICAL_MINIMUM, 0); 573 pack_parameter(&report, 0, 1, LOGICAL_MINIMUM, 0);
577 pack_parameter(&report, 0, 1, LOGICAL_MAXIMUM, 100); 574 pack_parameter(&report, 0, 1, LOGICAL_MAXIMUM, 100);
578 pack_parameter(&report, 0, 1, REPORT_SIZE, 8); 575 pack_parameter(&report, 0, 1, REPORT_SIZE, 8);
579 pack_parameter(&report, 0, 1, REPORT_COUNT, 1); 576 pack_parameter(&report, 0, 1, REPORT_COUNT, 1);
580 pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE); 577 pack_parameter(&report, 0, 1, FEATURE, MAIN_ITEM_VARIABLE);
581 PACK_VAL(report, END_COLLECTION); 578 PACK_VAL(report, END_COLLECTION);
582 579
583 return (size_t)(report - dest); 580 return (size_t)(report - dest);
@@ -622,7 +619,6 @@ void usb_hid_init_connection(void)
622 logf("hid: init connection"); 619 logf("hid: init connection");
623 active = true; 620 active = true;
624 currently_sending = false; 621 currently_sending = false;
625 set_battery_reporting(true);
626} 622}
627 623
628/* called by usb_core_init() */ 624/* called by usb_core_init() */
@@ -643,7 +639,6 @@ void usb_hid_init(void)
643void usb_hid_disconnect(void) 639void usb_hid_disconnect(void)
644{ 640{
645 logf("hid: disconnect"); 641 logf("hid: disconnect");
646 set_battery_reporting(false);
647 active = false; 642 active = false;
648 currently_sending = false; 643 currently_sending = false;
649} 644}
@@ -677,7 +672,7 @@ static int usb_hid_set_report(struct usb_ctrlrequest *req)
677 672
678 if ((req->wValue >> 8) != REPORT_TYPE_OUTPUT) 673 if ((req->wValue >> 8) != REPORT_TYPE_OUTPUT)
679 { 674 {
680 logf("Unsopported report type"); 675 logf("Unsupported report type");
681 return 1; 676 return 1;
682 } 677 }
683 if ((req->wValue & 0xff) != REPORT_ID_KEYBOARD) 678 if ((req->wValue & 0xff) != REPORT_ID_KEYBOARD)
@@ -718,14 +713,47 @@ static int usb_hid_set_report(struct usb_ctrlrequest *req)
718 return 0; 713 return 0;
719} 714}
720 715
716static int usb_hid_get_report(struct usb_ctrlrequest *req, unsigned char** dest)
717{
718 if ((req->wValue >> 8) != REPORT_TYPE_FEATURE)
719 {
720 logf("Unsupported report type");
721 return 1;
722 }
723
724 if ((req->wValue & 0xff) != REPORT_ID_BACKGROUND)
725 {
726 logf("Wrong report id");
727 return 2;
728 }
729
730 if (req->wIndex != (uint16_t)usb_interface)
731 {
732 logf("Wrong interface");
733 return 3;
734 }
735
736 if (req->wLength < GET_REPORT_BUF_LEN)
737 {
738 logf("Wrong length");
739 return 4;
740 }
741
742 (*dest)[0] = 0;
743 (*dest)[1] = battery_level();
744 *dest += GET_REPORT_BUF_LEN;
745
746 return 0;
747}
748
721/* called by usb_core_control_request() */ 749/* called by usb_core_control_request() */
722bool usb_hid_control_request(struct usb_ctrlrequest *req, unsigned char *dest) 750bool usb_hid_control_request(struct usb_ctrlrequest *req, unsigned char *dest)
723{ 751{
752 unsigned char *orig_dest = dest;
724 switch (req->bRequestType & USB_TYPE_MASK) 753 switch (req->bRequestType & USB_TYPE_MASK)
725 { 754 {
726 case USB_TYPE_STANDARD: 755 case USB_TYPE_STANDARD:
727 { 756 {
728 unsigned char *orig_dest = dest;
729 uint8_t type = req->wValue >> 8; 757 uint8_t type = req->wValue >> 8;
730 size_t len; 758 size_t len;
731 logf("hid: type %d %s", type, (type == USB_DT_HID) ? "hid" : 759 logf("hid: type %d %s", type, (type == USB_DT_HID) ? "hid" :
@@ -755,14 +783,26 @@ bool usb_hid_control_request(struct usb_ctrlrequest *req, unsigned char *dest)
755 { 783 {
756 logf("req %d %s", req->bRequest, 784 logf("req %d %s", req->bRequest,
757 (req->bRequest == USB_HID_SET_IDLE) ? "set idle" : 785 (req->bRequest == USB_HID_SET_IDLE) ? "set idle" :
758 ((req->bRequest == USB_HID_SET_REPORT) ? "set report" : "")); 786 ((req->bRequest == USB_HID_SET_REPORT) ? "set report" :
787 ((req->bRequest == USB_HID_GET_REPORT) ? "get report" : "")));
759 switch (req->bRequest) 788 switch (req->bRequest)
760 { 789 {
761 case USB_HID_SET_REPORT: 790 case USB_HID_SET_REPORT:
762 if (usb_hid_set_report(req)) 791 if (usb_hid_set_report(req))
763 break; 792 break;
793 case USB_HID_GET_REPORT:
794 if (usb_hid_get_report(req, &dest))
795 break;
764 case USB_HID_SET_IDLE: 796 case USB_HID_SET_IDLE:
765 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */ 797 if (dest != orig_dest)
798 {
799 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
800 usb_drv_send(EP_CONTROL, orig_dest, dest - orig_dest);
801 }
802 else
803 {
804 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
805 }
766 return true; 806 return true;
767 } 807 }
768 break; 808 break;