drivers: Add set_polling() method to drivers

When the driver needs to poll, ensure that we can easily disable that
polling to reduce wakeups.

This temporarily breaks the daemon.
This commit is contained in:
Bastien Nocera
2015-05-19 18:10:04 +02:00
parent 3ea494832b
commit 963ee096df
7 changed files with 140 additions and 44 deletions

View File

@@ -46,15 +46,16 @@ typedef void (*ReadingsUpdateFunc) (SensorDriver *driver,
gpointer user_data); gpointer user_data);
struct SensorDriver { struct SensorDriver {
const char *name; const char *name;
DriverType type; DriverType type;
DriverSpecificType specific_type; DriverSpecificType specific_type;
gboolean (*discover) (GUdevDevice *device); gboolean (*discover) (GUdevDevice *device);
gboolean (*open) (GUdevDevice *device, gboolean (*open) (GUdevDevice *device,
ReadingsUpdateFunc callback_func, ReadingsUpdateFunc callback_func,
gpointer user_data); gpointer user_data);
void (*close) (void); void (*set_polling) (gboolean state);
void (*close) (void);
}; };
extern SensorDriver iio_buffer_accel; extern SensorDriver iio_buffer_accel;

View File

@@ -64,6 +64,7 @@ first_values (gpointer user_data)
{ {
light_changed (); light_changed ();
drv_data->timeout_id = g_timeout_add_seconds (1, (GSourceFunc) light_changed, NULL); drv_data->timeout_id = g_timeout_add_seconds (1, (GSourceFunc) light_changed, NULL);
g_source_set_name_by_id (drv_data->timeout_id, "[fake_light_set_polling] light_changed");
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
@@ -76,18 +77,32 @@ fake_light_open (GUdevDevice *device,
drv_data->callback_func = callback_func; drv_data->callback_func = callback_func;
drv_data->user_data = user_data; drv_data->user_data = user_data;
drv_data->timeout_id = g_idle_add (first_values, NULL);
return TRUE; return TRUE;
} }
static void
fake_light_set_polling (gboolean state)
{
if (drv_data->timeout_id > 0 && state)
return;
if (drv_data->timeout_id == 0 && !state)
return;
if (drv_data->timeout_id) {
g_source_remove (drv_data->timeout_id);
drv_data->timeout_id = 0;
}
if (state) {
drv_data->timeout_id = g_idle_add (first_values, NULL);
g_source_set_name_by_id (drv_data->timeout_id, "[fake_light_set_polling] first_values");
}
}
static void static void
fake_light_close (void) fake_light_close (void)
{ {
if (drv_data->timeout_id != 0) { fake_light_set_polling (FALSE);
g_source_remove (drv_data->timeout_id);
drv_data->timeout_id = 0;
}
g_clear_pointer (&drv_data, g_free); g_clear_pointer (&drv_data, g_free);
} }
@@ -98,5 +113,6 @@ SensorDriver fake_light = {
.discover = fake_light_discover, .discover = fake_light_discover,
.open = fake_light_open, .open = fake_light_open,
.set_polling = fake_light_set_polling,
.close = fake_light_close, .close = fake_light_close,
}; };

View File

@@ -93,20 +93,32 @@ hwmon_light_open (GUdevDevice *device,
drv_data->light_path = g_build_filename (g_udev_device_get_sysfs_path (device), drv_data->light_path = g_build_filename (g_udev_device_get_sysfs_path (device),
"light", NULL); "light", NULL);
drv_data->timeout_id = g_timeout_add (DEFAULT_POLL_TIME,
(GSourceFunc) light_changed,
NULL);
return TRUE; return TRUE;
} }
static void
hwmon_light_set_polling (gboolean state)
{
if (drv_data->timeout_id > 0 && state)
return;
if (drv_data->timeout_id == 0 && !state)
return;
if (drv_data->timeout_id) {
g_source_remove (drv_data->timeout_id);
drv_data->timeout_id = 0;
}
if (state) {
drv_data->timeout_id = g_idle_add ((GSourceFunc) light_changed, NULL);
g_source_set_name_by_id (drv_data->timeout_id, "[hwmon_light_set_polling] light_changed");
}
}
static void static void
hwmon_light_close (void) hwmon_light_close (void)
{ {
if (drv_data->timeout_id != 0) { hwmon_light_set_polling (FALSE);
g_source_remove (drv_data->timeout_id);
drv_data->timeout_id = 0;
}
g_clear_pointer (&drv_data->light_path, g_free); g_clear_pointer (&drv_data->light_path, g_free);
g_clear_pointer (&drv_data, g_free); g_clear_pointer (&drv_data, g_free);
} }
@@ -118,5 +130,6 @@ SensorDriver hwmon_light = {
.discover = hwmon_light_discover, .discover = hwmon_light_discover,
.open = hwmon_light_open, .open = hwmon_light_open,
.set_polling = hwmon_light_set_polling,
.close = hwmon_light_close, .close = hwmon_light_close,
}; };

View File

@@ -166,6 +166,25 @@ iio_buffer_accel_discover (GUdevDevice *device)
return TRUE; return TRUE;
} }
static void
iio_buffer_accel_set_polling (gboolean state)
{
if (drv_data->timeout_id > 0 && state)
return;
if (drv_data->timeout_id == 0 && !state)
return;
if (drv_data->timeout_id) {
g_source_remove (drv_data->timeout_id);
drv_data->timeout_id = 0;
}
if (state) {
drv_data->timeout_id = g_timeout_add (700, read_orientation, drv_data);
g_source_set_name_by_id (drv_data->timeout_id, "[iio_buffer_accel_set_polling] read_orientation");
}
}
static gboolean static gboolean
iio_buffer_accel_open (GUdevDevice *device, iio_buffer_accel_open (GUdevDevice *device,
ReadingsUpdateFunc callback_func, ReadingsUpdateFunc callback_func,
@@ -195,16 +214,13 @@ iio_buffer_accel_open (GUdevDevice *device,
drv_data->callback_func = callback_func; drv_data->callback_func = callback_func;
drv_data->user_data = user_data; drv_data->user_data = user_data;
drv_data->timeout_id = g_timeout_add (700, read_orientation, drv_data);
g_source_set_name_by_id (drv_data->timeout_id, "read_orientation");
return TRUE; return TRUE;
} }
static void static void
iio_buffer_accel_close (void) iio_buffer_accel_close (void)
{ {
g_source_remove (drv_data->timeout_id); iio_buffer_accel_set_polling (FALSE);
g_clear_pointer (&drv_data->buffer_data, buffer_drv_data_free); g_clear_pointer (&drv_data->buffer_data, buffer_drv_data_free);
g_clear_object (&drv_data->dev); g_clear_object (&drv_data->dev);
g_clear_pointer (&drv_data, g_free); g_clear_pointer (&drv_data, g_free);
@@ -217,5 +233,6 @@ SensorDriver iio_buffer_accel = {
.discover = iio_buffer_accel_discover, .discover = iio_buffer_accel_discover,
.open = iio_buffer_accel_open, .open = iio_buffer_accel_open,
.set_polling = iio_buffer_accel_set_polling,
.close = iio_buffer_accel_close, .close = iio_buffer_accel_close,
}; };

View File

@@ -153,6 +153,25 @@ iio_buffer_light_discover (GUdevDevice *device)
return TRUE; return TRUE;
} }
static void
iio_buffer_light_set_polling (gboolean state)
{
if (drv_data->timeout_id > 0 && state)
return;
if (drv_data->timeout_id == 0 && !state)
return;
if (drv_data->timeout_id) {
g_source_remove (drv_data->timeout_id);
drv_data->timeout_id = 0;
}
if (state) {
drv_data->timeout_id = g_timeout_add (700, read_light, drv_data);
g_source_set_name_by_id (drv_data->timeout_id, "[iio_buffer_light_set_polling] read_light");
}
}
static gboolean static gboolean
iio_buffer_light_open (GUdevDevice *device, iio_buffer_light_open (GUdevDevice *device,
ReadingsUpdateFunc callback_func, ReadingsUpdateFunc callback_func,
@@ -182,16 +201,13 @@ iio_buffer_light_open (GUdevDevice *device,
drv_data->callback_func = callback_func; drv_data->callback_func = callback_func;
drv_data->user_data = user_data; drv_data->user_data = user_data;
drv_data->timeout_id = g_timeout_add (700, read_light, drv_data);
g_source_set_name_by_id (drv_data->timeout_id, "read_light");
return TRUE; return TRUE;
} }
static void static void
iio_buffer_light_close (void) iio_buffer_light_close (void)
{ {
g_source_remove (drv_data->timeout_id); iio_buffer_light_set_polling (FALSE);
g_clear_pointer (&drv_data->buffer_data, buffer_drv_data_free); g_clear_pointer (&drv_data->buffer_data, buffer_drv_data_free);
g_clear_object (&drv_data->dev); g_clear_object (&drv_data->dev);
g_clear_pointer (&drv_data, g_free); g_clear_pointer (&drv_data, g_free);
@@ -204,5 +220,6 @@ SensorDriver iio_buffer_light = {
.discover = iio_buffer_light_discover, .discover = iio_buffer_light_discover,
.open = iio_buffer_light_open, .open = iio_buffer_light_open,
.set_polling = iio_buffer_light_set_polling,
.close = iio_buffer_light_close, .close = iio_buffer_light_close,
}; };

View File

@@ -91,6 +91,25 @@ iio_poll_accel_discover (GUdevDevice *device)
return TRUE; return TRUE;
} }
static void
iio_poll_accel_set_polling (gboolean state)
{
if (drv_data->timeout_id > 0 && state)
return;
if (drv_data->timeout_id == 0 && !state)
return;
if (drv_data->timeout_id) {
g_source_remove (drv_data->timeout_id);
drv_data->timeout_id = 0;
}
if (state) {
drv_data->timeout_id = g_timeout_add (700, poll_orientation, drv_data);
g_source_set_name_by_id (drv_data->timeout_id, "[iio_poll_accel_set_polling] poll_orientation");
}
}
static gboolean static gboolean
iio_poll_accel_open (GUdevDevice *device, iio_poll_accel_open (GUdevDevice *device,
ReadingsUpdateFunc callback_func, ReadingsUpdateFunc callback_func,
@@ -105,16 +124,13 @@ iio_poll_accel_open (GUdevDevice *device,
if (drv_data->scale == 0.0) if (drv_data->scale == 0.0)
drv_data->scale = 1.0; drv_data->scale = 1.0;
drv_data->timeout_id = g_timeout_add (700, poll_orientation, drv_data);
g_source_set_name_by_id (drv_data->timeout_id, "poll_orientation");
return TRUE; return TRUE;
} }
static void static void
iio_poll_accel_close (void) iio_poll_accel_close (void)
{ {
g_source_remove (drv_data->timeout_id); iio_poll_accel_set_polling (FALSE);
g_clear_object (&drv_data->dev); g_clear_object (&drv_data->dev);
g_clear_pointer (&drv_data, g_free); g_clear_pointer (&drv_data, g_free);
} }
@@ -126,5 +142,6 @@ SensorDriver iio_poll_accel = {
.discover = iio_poll_accel_discover, .discover = iio_poll_accel_discover,
.open = iio_poll_accel_open, .open = iio_poll_accel_open,
.set_polling = iio_poll_accel_set_polling,
.close = iio_poll_accel_close, .close = iio_poll_accel_close,
}; };

View File

@@ -21,6 +21,7 @@ typedef struct DrvData {
gpointer user_data; gpointer user_data;
char *input_path; char *input_path;
guint interval;
guint timeout_id; guint timeout_id;
} DrvData; } DrvData;
@@ -91,24 +92,40 @@ get_interval (GUdevDevice *device)
return (time * 1000); return (time * 1000);
} }
static void
iio_poll_light_set_polling (gboolean state)
{
if (drv_data->timeout_id > 0 && state)
return;
if (drv_data->timeout_id == 0 && !state)
return;
if (drv_data->timeout_id) {
g_source_remove (drv_data->timeout_id);
drv_data->timeout_id = 0;
}
if (state) {
drv_data->timeout_id = g_timeout_add (drv_data->interval,
(GSourceFunc) light_changed,
NULL);
g_source_set_name_by_id (drv_data->timeout_id, "[iio_poll_light_set_polling] light_changed");
}
}
static gboolean static gboolean
iio_poll_light_open (GUdevDevice *device, iio_poll_light_open (GUdevDevice *device,
ReadingsUpdateFunc callback_func, ReadingsUpdateFunc callback_func,
gpointer user_data) gpointer user_data)
{ {
guint interval;
drv_data = g_new0 (DrvData, 1); drv_data = g_new0 (DrvData, 1);
drv_data->callback_func = callback_func; drv_data->callback_func = callback_func;
drv_data->user_data = user_data; drv_data->user_data = user_data;
interval = get_interval (device); drv_data->interval = get_interval (device);
drv_data->input_path = g_build_filename (g_udev_device_get_sysfs_path (device), drv_data->input_path = g_build_filename (g_udev_device_get_sysfs_path (device),
"in_illuminance_input", "in_illuminance_input",
NULL); NULL);
drv_data->timeout_id = g_timeout_add (interval,
(GSourceFunc) light_changed,
NULL);
return TRUE; return TRUE;
} }
@@ -116,10 +133,7 @@ iio_poll_light_open (GUdevDevice *device,
static void static void
iio_poll_light_close (void) iio_poll_light_close (void)
{ {
if (drv_data->timeout_id != 0) { iio_poll_light_set_polling (FALSE);
g_source_remove (drv_data->timeout_id);
drv_data->timeout_id = 0;
}
g_clear_pointer (&drv_data->input_path, g_free); g_clear_pointer (&drv_data->input_path, g_free);
g_clear_pointer (&drv_data, g_free); g_clear_pointer (&drv_data, g_free);
} }
@@ -131,5 +145,6 @@ SensorDriver iio_poll_light = {
.discover = iio_poll_light_discover, .discover = iio_poll_light_discover,
.open = iio_poll_light_open, .open = iio_poll_light_open,
.set_polling = iio_poll_light_set_polling,
.close = iio_poll_light_close, .close = iio_poll_light_close,
}; };