Skip to content

Commit aa984f1

Browse files
gwendalcrEnric Balletbo i Serra
authored andcommitted
iio: cros_ec: Register to cros_ec_sensorhub when EC supports FIFO
When EC supports FIFO, each IIO device registers a callback, to put samples in the buffer when they arrives from the FIFO. When no FIFO, the user space app needs to call trigger_new, or better register a high precision timer. Signed-off-by: Gwendal Grignou <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Signed-off-by: Enric Balletbo i Serra <[email protected]>
1 parent 69f0793 commit aa984f1

File tree

7 files changed

+119
-29
lines changed

7 files changed

+119
-29
lines changed

drivers/iio/accel/cros_ec_accel_legacy.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)
170170
if (!indio_dev)
171171
return -ENOMEM;
172172

173-
ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
173+
ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
174+
cros_ec_sensors_capture, NULL);
174175
if (ret)
175176
return ret;
176177

@@ -190,11 +191,6 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev)
190191
state->sign[CROS_EC_SENSOR_Z] = -1;
191192
}
192193

193-
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
194-
cros_ec_sensors_capture, NULL);
195-
if (ret)
196-
return ret;
197-
198194
return devm_iio_device_register(dev, indio_dev);
199195
}
200196

drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev)
9797
if (!indio_dev)
9898
return -ENOMEM;
9999

100-
ret = cros_ec_sensors_core_init(pdev, indio_dev, false);
100+
ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, NULL);
101101
if (ret)
102102
return ret;
103103

drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,9 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
230230
if (!indio_dev)
231231
return -ENOMEM;
232232

233-
ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
233+
ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
234+
cros_ec_sensors_capture,
235+
cros_ec_sensors_push_data);
234236
if (ret)
235237
return ret;
236238

@@ -292,11 +294,6 @@ static int cros_ec_sensors_probe(struct platform_device *pdev)
292294
else
293295
state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
294296

295-
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
296-
cros_ec_sensors_capture, NULL);
297-
if (ret)
298-
return ret;
299-
300297
return devm_iio_device_register(dev, indio_dev);
301298
}
302299

drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/iio/iio.h>
1313
#include <linux/iio/kfifo_buf.h>
1414
#include <linux/iio/trigger_consumer.h>
15+
#include <linux/iio/triggered_buffer.h>
1516
#include <linux/kernel.h>
1617
#include <linux/module.h>
1718
#include <linux/slab.h>
@@ -82,17 +83,71 @@ static void get_default_min_max_freq(enum motionsensor_type type,
8283
}
8384
}
8485

86+
int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
87+
s16 *data,
88+
s64 timestamp)
89+
{
90+
struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
91+
s16 *out;
92+
s64 delta;
93+
unsigned int i;
94+
95+
/*
96+
* Ignore samples if the buffer is not set: it is needed if the ODR is
97+
* set but the buffer is not enabled yet.
98+
*/
99+
if (!iio_buffer_enabled(indio_dev))
100+
return 0;
101+
102+
out = (s16 *)st->samples;
103+
for_each_set_bit(i,
104+
indio_dev->active_scan_mask,
105+
indio_dev->masklength) {
106+
*out = data[i];
107+
out++;
108+
}
109+
110+
if (iio_device_get_clock(indio_dev) != CLOCK_BOOTTIME)
111+
delta = iio_get_time_ns(indio_dev) - cros_ec_get_time_ns();
112+
else
113+
delta = 0;
114+
115+
iio_push_to_buffers_with_timestamp(indio_dev, st->samples,
116+
timestamp + delta);
117+
118+
return 0;
119+
}
120+
EXPORT_SYMBOL_GPL(cros_ec_sensors_push_data);
121+
122+
static void cros_ec_sensors_core_clean(void *arg)
123+
{
124+
struct platform_device *pdev = (struct platform_device *)arg;
125+
struct cros_ec_sensorhub *sensor_hub =
126+
dev_get_drvdata(pdev->dev.parent);
127+
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
128+
struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
129+
u8 sensor_num = st->param.info.sensor_num;
130+
131+
cros_ec_sensorhub_unregister_push_data(sensor_hub, sensor_num);
132+
}
133+
85134
/**
86135
* cros_ec_sensors_core_init() - basic initialization of the core structure
87136
* @pdev: platform device created for the sensors
88137
* @indio_dev: iio device structure of the device
89138
* @physical_device: true if the device refers to a physical device
139+
* @trigger_capture: function pointer to call buffer is triggered,
140+
* for backward compatibility.
141+
* @push_data: function to call when cros_ec_sensorhub receives
142+
* a sample for that sensor.
90143
*
91144
* Return: 0 on success, -errno on failure.
92145
*/
93146
int cros_ec_sensors_core_init(struct platform_device *pdev,
94147
struct iio_dev *indio_dev,
95-
bool physical_device)
148+
bool physical_device,
149+
cros_ec_sensors_capture_t trigger_capture,
150+
cros_ec_sensorhub_push_data_cb_t push_data)
96151
{
97152
struct device *dev = &pdev->dev;
98153
struct cros_ec_sensors_core_state *state = iio_priv(indio_dev);
@@ -131,8 +186,6 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
131186
indio_dev->name = pdev->name;
132187

133188
if (physical_device) {
134-
indio_dev->modes = INDIO_DIRECT_MODE;
135-
136189
state->param.cmd = MOTIONSENSE_CMD_INFO;
137190
state->param.info.sensor_num = sensor_platform->sensor_num;
138191
ret = cros_ec_motion_send_host_cmd(state, 0);
@@ -161,6 +214,48 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
161214
state->frequencies[2] =
162215
state->resp->info_3.max_frequency;
163216
}
217+
218+
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE_FIFO)) {
219+
/*
220+
* Create a software buffer, feed by the EC FIFO.
221+
* We can not use trigger here, as events are generated
222+
* as soon as sample_frequency is set.
223+
*/
224+
struct iio_buffer *buffer;
225+
226+
buffer = devm_iio_kfifo_allocate(dev);
227+
if (!buffer)
228+
return -ENOMEM;
229+
230+
iio_device_attach_buffer(indio_dev, buffer);
231+
indio_dev->modes = INDIO_BUFFER_SOFTWARE;
232+
233+
ret = cros_ec_sensorhub_register_push_data(
234+
sensor_hub, sensor_platform->sensor_num,
235+
indio_dev, push_data);
236+
if (ret)
237+
return ret;
238+
239+
ret = devm_add_action_or_reset(
240+
dev, cros_ec_sensors_core_clean, pdev);
241+
if (ret)
242+
return ret;
243+
244+
/* Timestamp coming from FIFO are in ns since boot. */
245+
ret = iio_device_set_clock(indio_dev, CLOCK_BOOTTIME);
246+
if (ret)
247+
return ret;
248+
} else {
249+
/*
250+
* The only way to get samples in buffer is to set a
251+
* software tigger (systrig, hrtimer).
252+
*/
253+
ret = devm_iio_triggered_buffer_setup(
254+
dev, indio_dev, NULL, trigger_capture,
255+
NULL);
256+
if (ret)
257+
return ret;
258+
}
164259
}
165260

166261
return 0;

drivers/iio/light/cros_ec_light_prox.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
177177
if (!indio_dev)
178178
return -ENOMEM;
179179

180-
ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
180+
ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
181+
cros_ec_sensors_capture,
182+
cros_ec_sensors_push_data);
181183
if (ret)
182184
return ret;
183185

@@ -236,11 +238,6 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev)
236238

237239
state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
238240

239-
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
240-
cros_ec_sensors_capture, NULL);
241-
if (ret)
242-
return ret;
243-
244241
return devm_iio_device_register(dev, indio_dev);
245242
}
246243

drivers/iio/pressure/cros_ec_baro.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
134134
if (!indio_dev)
135135
return -ENOMEM;
136136

137-
ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
137+
ret = cros_ec_sensors_core_init(pdev, indio_dev, true,
138+
cros_ec_sensors_capture,
139+
cros_ec_sensors_push_data);
138140
if (ret)
139141
return ret;
140142

@@ -182,11 +184,6 @@ static int cros_ec_baro_probe(struct platform_device *pdev)
182184

183185
state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
184186

185-
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
186-
cros_ec_sensors_capture, NULL);
187-
if (ret)
188-
return ret;
189-
190187
return devm_iio_device_register(dev, indio_dev);
191188
}
192189

include/linux/iio/common/cros_ec_sensors_core.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/irqreturn.h>
1313
#include <linux/platform_data/cros_ec_commands.h>
1414
#include <linux/platform_data/cros_ec_proto.h>
15+
#include <linux/platform_data/cros_ec_sensorhub.h>
1516

1617
enum {
1718
CROS_EC_SENSOR_X,
@@ -32,6 +33,8 @@ enum {
3233
/* Minimum sampling period to use when device is suspending */
3334
#define CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY 1000 /* 1 second */
3435

36+
typedef irqreturn_t (*cros_ec_sensors_capture_t)(int irq, void *p);
37+
3538
/**
3639
* struct cros_ec_sensors_core_state - state data for EC sensors IIO driver
3740
* @ec: cros EC device structure
@@ -87,9 +90,14 @@ int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev, unsigned long scan_mask,
8790

8891
struct platform_device;
8992
int cros_ec_sensors_core_init(struct platform_device *pdev,
90-
struct iio_dev *indio_dev, bool physical_device);
93+
struct iio_dev *indio_dev, bool physical_device,
94+
cros_ec_sensors_capture_t trigger_capture,
95+
cros_ec_sensorhub_push_data_cb_t push_data);
9196

9297
irqreturn_t cros_ec_sensors_capture(int irq, void *p);
98+
int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
99+
s16 *data,
100+
s64 timestamp);
93101

94102
int cros_ec_motion_send_host_cmd(struct cros_ec_sensors_core_state *st,
95103
u16 opt_length);

0 commit comments

Comments
 (0)