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
170 if (!indio_dev)170 if (!indio_dev)
171 return -ENOMEM;171 return -ENOMEM;
172 172
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);
174 if (ret)175 if (ret)
175 return ret;176 return ret;
176 177
@@ -190,11 +191,6 @@ static int cros_ec_accel_legacy_probe(struct platform_device *pdev) · 13 unmodified lines
190 state->sign[CROS_EC_SENSOR_Z] = -1;191 state->sign[CROS_EC_SENSOR_Z] = -1;
191 }192 }
192 193
193 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
194 cros_ec_sensors_capture, NULL);
195 if (ret)
196 return ret;
197
198 return devm_iio_device_register(dev, indio_dev);194 return devm_iio_device_register(dev, indio_dev);
199}195}
200 196
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
97 if (!indio_dev)97 if (!indio_dev)
98 return -ENOMEM;98 return -ENOMEM;
99 99
100 ret = cros_ec_sensors_core_init(pdev, indio_dev, false);100 ret = cros_ec_sensors_core_init(pdev, indio_dev, false, NULL, NULL);
101 if (ret)101 if (ret)
102 return ret;102 return ret;
103 103
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
230 if (!indio_dev)230 if (!indio_dev)
231 return -ENOMEM;231 return -ENOMEM;
232 232
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);
234 if (ret)236 if (ret)
235 return ret;237 return ret;
236 238
@@ -292,11 +294,6 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) · 55 unmodified lines
292 else294 else
293 state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;295 state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
294 296
295 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
296 cros_ec_sensors_capture, NULL);
297 if (ret)
298 return ret;
299
300 return devm_iio_device_register(dev, indio_dev);297 return devm_iio_device_register(dev, indio_dev);
301}298}
302 299
drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c+98−3
@@ -12,6 +12,7 @@ · 11 unmodified lines
12#include <linux/iio/iio.h>12#include <linux/iio/iio.h>
13#include <linux/iio/kfifo_buf.h>13#include <linux/iio/kfifo_buf.h>
14#include <linux/iio/trigger_consumer.h>14#include <linux/iio/trigger_consumer.h>
15#include <linux/iio/triggered_buffer.h>
15#include <linux/kernel.h>16#include <linux/kernel.h>
16#include <linux/module.h>17#include <linux/module.h>
17#include <linux/slab.h>18#include <linux/slab.h>
@@ -82,17 +83,71 @@ static void get_default_min_max_freq(enum motionsensor_type type, · 64 unmodified lines
82 }83 }
83}84}
84 85
86int 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}
120EXPORT_SYMBOL_GPL(cros_ec_sensors_push_data);
121
122static 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
85/**134/**
86 * cros_ec_sensors_core_init() - basic initialization of the core structure135 * cros_ec_sensors_core_init() - basic initialization of the core structure
87 * @pdev: platform device created for the sensors136 * @pdev: platform device created for the sensors
88 * @indio_dev: iio device structure of the device137 * @indio_dev: iio device structure of the device
89 * @physical_device: true if the device refers to a physical device138 * @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.
90 *143 *
91 * Return: 0 on success, -errno on failure.144 * Return: 0 on success, -errno on failure.
92 */145 */
93int cros_ec_sensors_core_init(struct platform_device *pdev,146int cros_ec_sensors_core_init(struct platform_device *pdev,
94 struct iio_dev *indio_dev,147 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)
96{151{
97 struct device *dev = &pdev->dev;152 struct device *dev = &pdev->dev;
98 struct cros_ec_sensors_core_state *state = iio_priv(indio_dev);153 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
131 indio_dev->name = pdev->name;186 indio_dev->name = pdev->name;
132 187
133 if (physical_device) {188 if (physical_device) {
134 indio_dev->modes = INDIO_DIRECT_MODE;
135
136 state->param.cmd = MOTIONSENSE_CMD_INFO;189 state->param.cmd = MOTIONSENSE_CMD_INFO;
137 state->param.info.sensor_num = sensor_platform->sensor_num;190 state->param.info.sensor_num = sensor_platform->sensor_num;
138 ret = cros_ec_motion_send_host_cmd(state, 0);191 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
161 state->frequencies[2] =214 state->frequencies[2] =
162 state->resp->info_3.max_frequency;215 state->resp->info_3.max_frequency;
163 }216 }
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 }
164 }259 }
165 260
166 return 0;261 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
177 if (!indio_dev)177 if (!indio_dev)
178 return -ENOMEM;178 return -ENOMEM;
179 179
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);
181 if (ret)183 if (ret)
182 return ret;184 return ret;
183 185
@@ -236,11 +238,6 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) · 52 unmodified lines
236 238
237 state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;239 state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
238 240
239 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
240 cros_ec_sensors_capture, NULL);
241 if (ret)
242 return ret;
243
244 return devm_iio_device_register(dev, indio_dev);241 return devm_iio_device_register(dev, indio_dev);
245}242}
246 243
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
134 if (!indio_dev)134 if (!indio_dev)
135 return -ENOMEM;135 return -ENOMEM;
136 136
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);
138 if (ret)140 if (ret)
139 return ret;141 return ret;
140 142
@@ -182,11 +184,6 @@ static int cros_ec_baro_probe(struct platform_device *pdev) · 41 unmodified lines
182 184
183 state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;185 state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
184 186
185 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
186 cros_ec_sensors_capture, NULL);
187 if (ret)
188 return ret;
189
190 return devm_iio_device_register(dev, indio_dev);187 return devm_iio_device_register(dev, indio_dev);
191}188}
192 189
include/linux/iio/common/cros_ec_sensors_core.h+9−1
@@ -12,6 +12,7 @@ · 11 unmodified lines
12#include <linux/irqreturn.h>12#include <linux/irqreturn.h>
13#include <linux/platform_data/cros_ec_commands.h>13#include <linux/platform_data/cros_ec_commands.h>
14#include <linux/platform_data/cros_ec_proto.h>14#include <linux/platform_data/cros_ec_proto.h>
15#include <linux/platform_data/cros_ec_sensorhub.h>
15 16
16enum {17enum {
17 CROS_EC_SENSOR_X,18 CROS_EC_SENSOR_X,
@@ -32,6 +33,8 @@ enum { · 14 unmodified lines
32/* Minimum sampling period to use when device is suspending */33/* Minimum sampling period to use when device is suspending */
33#define CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY 1000 /* 1 second */34#define CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY 1000 /* 1 second */
34 35
36typedef irqreturn_t (*cros_ec_sensors_capture_t)(int irq, void *p);
37
35/**38/**
36 * struct cros_ec_sensors_core_state - state data for EC sensors IIO driver39 * struct cros_ec_sensors_core_state - state data for EC sensors IIO driver
37 * @ec: cros EC device structure40 * @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
87 90
88struct platform_device;91struct platform_device;
89int cros_ec_sensors_core_init(struct platform_device *pdev,92int 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);
91 96
92irqreturn_t cros_ec_sensors_capture(int irq, void *p);97irqreturn_t cros_ec_sensors_capture(int irq, void *p);
98int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
99 s16 *data,
100 s64 timestamp);
93 101
94int cros_ec_motion_send_host_cmd(struct cros_ec_sensors_core_state *st,102int cros_ec_motion_send_host_cmd(struct cros_ec_sensors_core_state *st,
95 u16 opt_length);103 u16 opt_length);