History

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.

Gwendal Grignou committed 6 years ago

Commit aa984f11 parent 69f07937 files · +119 −29Browse files

Unified · Split

7 files
  1. drivers/iio/accel/cros_ec_accel_legacy.c +2 −6
  2. drivers/iio/common/cros_ec_sensors/cros_ec_lid_angle.c +1 −1
  3. drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c +3 −6
  4. drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +98 −3
  5. drivers/iio/light/cros_ec_light_prox.c +3 −6
  6. drivers/iio/pressure/cros_ec_baro.c +3 −6
  7. include/linux/iio/common/cros_ec_sensors_core.h +9 −1
drivers/iio/accel/cros_ec_accel_legacy.c+2−6
@@ -170,7 +170,8 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev) · 169 unmodified lines
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) · 13 unmodified lines
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+1−1
@@ -97,7 +97,7 @@ static int cros_ec_lid_angle_probe(struct platform_device *pdev) · 96 unmodified lines
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+3−6
@@ -230,7 +230,9 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) · 229 unmodified lines
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) · 55 unmodified lines
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+98−3
@@ -12,6 +12,7 @@ · 11 unmodified lines
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, · 64 unmodified lines
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, · 32 unmodified lines
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, · 22 unmodified lines
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+3−6
@@ -177,7 +177,9 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) · 176 unmodified lines
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) · 52 unmodified lines
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+3−6
@@ -134,7 +134,9 @@ static int cros_ec_baro_probe(struct platform_device *pdev) · 133 unmodified lines
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) · 41 unmodified lines
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+9−1
@@ -12,6 +12,7 @@ · 11 unmodified lines
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 { · 14 unmodified lines
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, · 49 unmodified lines
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);