Commit ccf26dcd authored by Ryan Pavlik's avatar Ryan Pavlik Committed by Jakob Bornecrantz
Browse files

os/hid: Add support for get/set feature reports.

parent 2b006d5d
......@@ -4,6 +4,7 @@
* @file
* @brief Wrapper around OS native hid functions.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
*
* @ingroup aux_os
*/
......@@ -32,12 +33,23 @@ struct os_hid_device
const uint8_t *data,
size_t size);
int (*get_feature)(struct os_hid_device *hid_dev,
uint8_t report_num,
uint8_t *data,
size_t size);
int (*set_feature)(struct os_hid_device *hid_dev,
const uint8_t *data,
size_t size);
void (*destroy)(struct os_hid_device *hid_dev);
};
/*!
* Read from the given hid device, if milliseconds are negative blocks, 0 polls
* and positive will block for that amount of seconds.
* Read the next input report, if any, from the given hid device.
*
* If milliseconds are negative, this call blocks indefinitely, 0 polls,
* and positive will block for that amount of milliseconds.
*/
XRT_MAYBE_UNUSED static inline int
os_hid_read(struct os_hid_device *hid_dev,
......@@ -49,7 +61,7 @@ os_hid_read(struct os_hid_device *hid_dev,
}
/*!
* Write to the given device.
* Write an output report to the given device.
*/
XRT_MAYBE_UNUSED static inline int
os_hid_write(struct os_hid_device *hid_dev, const uint8_t *data, size_t size)
......@@ -57,6 +69,35 @@ os_hid_write(struct os_hid_device *hid_dev, const uint8_t *data, size_t size)
return hid_dev->write(hid_dev, data, size);
}
/*!
* Get a numbered feature report.
*
* If the device doesn't have more than one feature report, just request
* report 0.
*/
XRT_MAYBE_UNUSED static inline int
os_hid_get_feature(struct os_hid_device *hid_dev,
uint8_t report_num,
uint8_t *data,
size_t size)
{
return hid_dev->get_feature(hid_dev, report_num, data, size);
}
/*!
* Set a feature report.
*
* The first byte of the buffer is the report number, to be followed by
* the data of the report.
*/
XRT_MAYBE_UNUSED static inline int
os_hid_set_feature(struct os_hid_device *hid_dev,
const uint8_t *data,
size_t size)
{
return hid_dev->set_feature(hid_dev, data, size);
}
/*!
* Close and free the given device.
*/
......
......@@ -4,6 +4,7 @@
* @file
* @brief Hid implementation based on hidraw.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
* @ingroup aux_os
*/
......@@ -75,6 +76,29 @@ os_hidraw_write(struct os_hid_device *ohdev, const uint8_t *data, size_t length)
return write(hrdev->fd, data, length);
}
static int
os_hidraw_get_feature(struct os_hid_device *ohdev,
uint8_t report_num,
uint8_t *data,
size_t length)
{
struct hid_hidraw *hrdev = (struct hid_hidraw *)ohdev;
// The ioctl expects the report number in the first byte of the buffer,
// but it will overwrite it.
data[0] = report_num;
return ioctl(hrdev->fd, HIDIOCGFEATURE(length), data);
}
static int
os_hidraw_set_feature(struct os_hid_device *ohdev,
const uint8_t *data,
size_t length)
{
struct hid_hidraw *hrdev = (struct hid_hidraw *)ohdev;
return ioctl(hrdev->fd, HIDIOCSFEATURE(length), data);
}
static void
os_hidraw_destroy(struct os_hid_device *ohdev)
{
......@@ -91,6 +115,8 @@ os_hid_open_hidraw(const char *path, struct os_hid_device **out_ohdev)
hrdev->base.read = os_hidraw_read;
hrdev->base.write = os_hidraw_write;
hrdev->base.get_feature = os_hidraw_get_feature;
hrdev->base.set_feature = os_hidraw_set_feature;
hrdev->base.destroy = os_hidraw_destroy;
hrdev->fd = open(path, O_RDWR);
if (hrdev->fd < 0) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment