main: Add support for input driver accelerometers
This commit is contained in:
@@ -4,7 +4,8 @@ iio_sensor_proxy_SOURCES = \
|
||||
iio-sensor-proxy.c \
|
||||
drivers.h \
|
||||
drv-iio-buffer-accel.c \
|
||||
drv-iio-poll-accel.c
|
||||
drv-iio-poll-accel.c \
|
||||
drv-input-accel.c
|
||||
|
||||
iio_sensor_proxy_CPPFLAGS = \
|
||||
$(IIO_SENSOR_PROXY_CFLAGS) \
|
||||
|
@@ -10,7 +10,8 @@
|
||||
#include <gudev/gudev.h>
|
||||
|
||||
typedef enum {
|
||||
DRIVER_TYPE_ACCEL_IIO
|
||||
DRIVER_TYPE_ACCEL_IIO,
|
||||
DRIVER_TYPE_ACCEL_INPUT
|
||||
} DriverType;
|
||||
|
||||
typedef struct SensorDriver SensorDriver;
|
||||
@@ -34,3 +35,4 @@ struct SensorDriver {
|
||||
|
||||
extern SensorDriver iio_buffer_accel;
|
||||
extern SensorDriver iio_poll_accel;
|
||||
extern SensorDriver input_accel;
|
||||
|
135
src/drv-input-accel.c
Normal file
135
src/drv-input-accel.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Bastien Nocera <hadess@hadess.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include "drivers.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <linux/input.h>
|
||||
|
||||
typedef struct DrvData {
|
||||
ReadingsUpdateFunc callback_func;
|
||||
gpointer user_data;
|
||||
|
||||
GUdevClient *client;
|
||||
GUdevDevice *dev, *parent;
|
||||
const char *dev_path;
|
||||
} DrvData;
|
||||
|
||||
static DrvData *drv_data = NULL;
|
||||
|
||||
static gboolean
|
||||
input_accel_discover (GUdevDevice *device)
|
||||
{
|
||||
const char *path;
|
||||
|
||||
if (!g_udev_device_get_property_as_boolean (device, "ID_INPUT_ACCELEROMETER"))
|
||||
return FALSE;
|
||||
|
||||
path = g_udev_device_get_device_file (device);
|
||||
if (!path)
|
||||
return FALSE;
|
||||
if (strstr (path, "/event") == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_debug ("Found input accel at %s", g_udev_device_get_sysfs_path (device));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define READ_AXIS(axis, var) { memzero(&abs_info, sizeof(abs_info)); r = ioctl(fd, EVIOCGABS(axis), &abs_info); if (r < 0) return; var = abs_info.value; }
|
||||
#define memzero(x,l) (memset((x), 0, (l)))
|
||||
|
||||
static void
|
||||
accelerometer_changed (void)
|
||||
{
|
||||
struct input_absinfo abs_info;
|
||||
int accel_x = 0, accel_y = 0, accel_z = 0;
|
||||
int fd, r;
|
||||
|
||||
fd = open (drv_data->dev_path, O_RDONLY|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
READ_AXIS(ABS_X, accel_x);
|
||||
READ_AXIS(ABS_Y, accel_y);
|
||||
READ_AXIS(ABS_Z, accel_z);
|
||||
|
||||
close (fd);
|
||||
|
||||
drv_data->callback_func (&input_accel, accel_x, accel_y, accel_z, drv_data->user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
uevent_received (GUdevClient *client,
|
||||
gchar *action,
|
||||
GUdevDevice *device,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (g_strcmp0 (action, "change") != 0)
|
||||
return;
|
||||
|
||||
if (g_strcmp0 (g_udev_device_get_sysfs_path (device), g_udev_device_get_sysfs_path (drv_data->parent)) != 0)
|
||||
return;
|
||||
|
||||
accelerometer_changed ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
first_values (gpointer user_data)
|
||||
{
|
||||
accelerometer_changed ();
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
input_accel_open (GUdevDevice *device,
|
||||
ReadingsUpdateFunc callback_func,
|
||||
gpointer user_data)
|
||||
{
|
||||
const gchar * const subsystems[] = { "input", NULL };
|
||||
|
||||
drv_data = g_new0 (DrvData, 1);
|
||||
drv_data->dev = g_object_ref (device);
|
||||
drv_data->parent = g_udev_device_get_parent (drv_data->dev);
|
||||
drv_data->dev_path = g_udev_device_get_device_file (device);
|
||||
drv_data->client = g_udev_client_new (subsystems);
|
||||
|
||||
drv_data->callback_func = callback_func;
|
||||
drv_data->user_data = user_data;
|
||||
|
||||
g_signal_connect (drv_data->client, "uevent",
|
||||
G_CALLBACK (uevent_received), NULL);
|
||||
|
||||
g_idle_add (first_values, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
input_accel_close (void)
|
||||
{
|
||||
g_clear_object (&drv_data->client);
|
||||
g_clear_object (&drv_data->dev);
|
||||
g_clear_object (&drv_data->parent);
|
||||
g_clear_pointer (&drv_data->dev_path, g_free);
|
||||
|
||||
g_clear_pointer (&drv_data, g_free);
|
||||
}
|
||||
|
||||
SensorDriver input_accel = {
|
||||
.name = "Input accelerometer",
|
||||
.type = DRIVER_TYPE_ACCEL_INPUT,
|
||||
|
||||
.discover = input_accel_discover,
|
||||
.open = input_accel_open,
|
||||
.close = input_accel_close,
|
||||
};
|
@@ -159,18 +159,21 @@ typedef struct {
|
||||
|
||||
static const SensorDriver * const drivers[] = {
|
||||
&iio_buffer_accel,
|
||||
&iio_poll_accel
|
||||
&iio_poll_accel,
|
||||
&input_accel
|
||||
};
|
||||
|
||||
static GUdevDevice *
|
||||
find_accel (GUdevClient *client,
|
||||
SensorDriver **driver)
|
||||
{
|
||||
GList *devices, *l;
|
||||
GList *devices, *input, *l;
|
||||
GUdevDevice *ret = NULL;
|
||||
|
||||
*driver = NULL;
|
||||
devices = g_udev_client_query_by_subsystem (client, "iio");
|
||||
input = g_udev_client_query_by_subsystem (client, "input");
|
||||
devices = g_list_concat (devices, input);
|
||||
|
||||
/* Find the accelerometer */
|
||||
for (l = devices; l != NULL; l = l->next) {
|
||||
@@ -346,12 +349,11 @@ int main (int argc, char **argv)
|
||||
GUdevClient *client;
|
||||
GUdevDevice *dev;
|
||||
SensorDriver *driver;
|
||||
const gchar * const subsystems[] = { "iio", NULL };
|
||||
int ret = 0;
|
||||
|
||||
/* g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); */
|
||||
|
||||
client = g_udev_client_new (subsystems);
|
||||
client = g_udev_client_new (NULL);
|
||||
dev = find_accel (client, &driver);
|
||||
if (!dev) {
|
||||
g_debug ("Could not find IIO accelerometer");
|
||||
|
Reference in New Issue
Block a user