1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Freescale MMA9551L Intelligent Motion-Sensing Platform driver |
4 | * Copyright (c) 2014, Intel Corporation. |
5 | */ |
6 | |
7 | #include <linux/module.h> |
8 | #include <linux/i2c.h> |
9 | #include <linux/interrupt.h> |
10 | #include <linux/slab.h> |
11 | #include <linux/acpi.h> |
12 | #include <linux/delay.h> |
13 | #include <linux/gpio/consumer.h> |
14 | #include <linux/iio/iio.h> |
15 | #include <linux/iio/sysfs.h> |
16 | #include <linux/iio/events.h> |
17 | #include <linux/pm_runtime.h> |
18 | #include "mma9551_core.h" |
19 | |
20 | #define MMA9551_DRV_NAME "mma9551" |
21 | #define MMA9551_IRQ_NAME "mma9551_event" |
22 | #define MMA9551_GPIO_COUNT 4 |
23 | |
24 | /* Tilt application (inclination in IIO terms). */ |
25 | #define MMA9551_TILT_XZ_ANG_REG 0x00 |
26 | #define MMA9551_TILT_YZ_ANG_REG 0x01 |
27 | #define MMA9551_TILT_XY_ANG_REG 0x02 |
28 | #define MMA9551_TILT_ANGFLG BIT(7) |
29 | #define MMA9551_TILT_QUAD_REG 0x03 |
30 | #define MMA9551_TILT_XY_QUAD_SHIFT 0 |
31 | #define MMA9551_TILT_YZ_QUAD_SHIFT 2 |
32 | #define MMA9551_TILT_XZ_QUAD_SHIFT 4 |
33 | #define MMA9551_TILT_CFG_REG 0x01 |
34 | #define MMA9551_TILT_ANG_THRESH_MASK GENMASK(3, 0) |
35 | |
36 | #define MMA9551_DEFAULT_SAMPLE_RATE 122 /* Hz */ |
37 | |
38 | /* Tilt events are mapped to the first three GPIO pins. */ |
39 | enum mma9551_tilt_axis { |
40 | mma9551_x = 0, |
41 | mma9551_y, |
42 | mma9551_z, |
43 | }; |
44 | |
45 | struct mma9551_data { |
46 | struct i2c_client *client; |
47 | struct mutex mutex; |
48 | int event_enabled[3]; |
49 | int irqs[MMA9551_GPIO_COUNT]; |
50 | }; |
51 | |
52 | static int mma9551_read_incli_chan(struct i2c_client *client, |
53 | const struct iio_chan_spec *chan, |
54 | int *val) |
55 | { |
56 | u8 quad_shift, angle, quadrant; |
57 | u16 reg_addr; |
58 | int ret; |
59 | |
60 | switch (chan->channel2) { |
61 | case IIO_MOD_X: |
62 | reg_addr = MMA9551_TILT_YZ_ANG_REG; |
63 | quad_shift = MMA9551_TILT_YZ_QUAD_SHIFT; |
64 | break; |
65 | case IIO_MOD_Y: |
66 | reg_addr = MMA9551_TILT_XZ_ANG_REG; |
67 | quad_shift = MMA9551_TILT_XZ_QUAD_SHIFT; |
68 | break; |
69 | case IIO_MOD_Z: |
70 | reg_addr = MMA9551_TILT_XY_ANG_REG; |
71 | quad_shift = MMA9551_TILT_XY_QUAD_SHIFT; |
72 | break; |
73 | default: |
74 | return -EINVAL; |
75 | } |
76 | |
77 | ret = mma9551_set_power_state(client, on: true); |
78 | if (ret < 0) |
79 | return ret; |
80 | |
81 | ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT, |
82 | reg: reg_addr, val: &angle); |
83 | if (ret < 0) |
84 | goto out_poweroff; |
85 | |
86 | ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT, |
87 | MMA9551_TILT_QUAD_REG, val: &quadrant); |
88 | if (ret < 0) |
89 | goto out_poweroff; |
90 | |
91 | angle &= ~MMA9551_TILT_ANGFLG; |
92 | quadrant = (quadrant >> quad_shift) & 0x03; |
93 | |
94 | if (quadrant == 1 || quadrant == 3) |
95 | *val = 90 * (quadrant + 1) - angle; |
96 | else |
97 | *val = angle + 90 * quadrant; |
98 | |
99 | ret = IIO_VAL_INT; |
100 | |
101 | out_poweroff: |
102 | mma9551_set_power_state(client, on: false); |
103 | return ret; |
104 | } |
105 | |
106 | static int mma9551_read_raw(struct iio_dev *indio_dev, |
107 | struct iio_chan_spec const *chan, |
108 | int *val, int *val2, long mask) |
109 | { |
110 | struct mma9551_data *data = iio_priv(indio_dev); |
111 | int ret; |
112 | |
113 | switch (mask) { |
114 | case IIO_CHAN_INFO_PROCESSED: |
115 | switch (chan->type) { |
116 | case IIO_INCLI: |
117 | mutex_lock(&data->mutex); |
118 | ret = mma9551_read_incli_chan(client: data->client, chan, val); |
119 | mutex_unlock(lock: &data->mutex); |
120 | return ret; |
121 | default: |
122 | return -EINVAL; |
123 | } |
124 | case IIO_CHAN_INFO_RAW: |
125 | switch (chan->type) { |
126 | case IIO_ACCEL: |
127 | mutex_lock(&data->mutex); |
128 | ret = mma9551_read_accel_chan(client: data->client, |
129 | chan, val, val2); |
130 | mutex_unlock(lock: &data->mutex); |
131 | return ret; |
132 | default: |
133 | return -EINVAL; |
134 | } |
135 | case IIO_CHAN_INFO_SCALE: |
136 | switch (chan->type) { |
137 | case IIO_ACCEL: |
138 | return mma9551_read_accel_scale(val, val2); |
139 | default: |
140 | return -EINVAL; |
141 | } |
142 | default: |
143 | return -EINVAL; |
144 | } |
145 | } |
146 | |
147 | static int mma9551_read_event_config(struct iio_dev *indio_dev, |
148 | const struct iio_chan_spec *chan, |
149 | enum iio_event_type type, |
150 | enum iio_event_direction dir) |
151 | { |
152 | struct mma9551_data *data = iio_priv(indio_dev); |
153 | |
154 | switch (chan->type) { |
155 | case IIO_INCLI: |
156 | /* IIO counts axes from 1, because IIO_NO_MOD is 0. */ |
157 | return data->event_enabled[chan->channel2 - 1]; |
158 | default: |
159 | return -EINVAL; |
160 | } |
161 | } |
162 | |
163 | static int mma9551_config_incli_event(struct iio_dev *indio_dev, |
164 | enum iio_modifier axis, |
165 | int state) |
166 | { |
167 | struct mma9551_data *data = iio_priv(indio_dev); |
168 | enum mma9551_tilt_axis mma_axis; |
169 | int ret; |
170 | |
171 | /* IIO counts axes from 1, because IIO_NO_MOD is 0. */ |
172 | mma_axis = axis - 1; |
173 | |
174 | if (data->event_enabled[mma_axis] == state) |
175 | return 0; |
176 | |
177 | if (state == 0) { |
178 | ret = mma9551_gpio_config(client: data->client, |
179 | pin: (enum mma9551_gpio_pin)mma_axis, |
180 | MMA9551_APPID_NONE, bitnum: 0, polarity: 0); |
181 | if (ret < 0) |
182 | return ret; |
183 | |
184 | ret = mma9551_set_power_state(client: data->client, on: false); |
185 | if (ret < 0) |
186 | return ret; |
187 | } else { |
188 | int bitnum; |
189 | |
190 | /* Bit 7 of each angle register holds the angle flag. */ |
191 | switch (axis) { |
192 | case IIO_MOD_X: |
193 | bitnum = 7 + 8 * MMA9551_TILT_YZ_ANG_REG; |
194 | break; |
195 | case IIO_MOD_Y: |
196 | bitnum = 7 + 8 * MMA9551_TILT_XZ_ANG_REG; |
197 | break; |
198 | case IIO_MOD_Z: |
199 | bitnum = 7 + 8 * MMA9551_TILT_XY_ANG_REG; |
200 | break; |
201 | default: |
202 | return -EINVAL; |
203 | } |
204 | |
205 | |
206 | ret = mma9551_set_power_state(client: data->client, on: true); |
207 | if (ret < 0) |
208 | return ret; |
209 | |
210 | ret = mma9551_gpio_config(client: data->client, |
211 | pin: (enum mma9551_gpio_pin)mma_axis, |
212 | MMA9551_APPID_TILT, bitnum, polarity: 0); |
213 | if (ret < 0) { |
214 | mma9551_set_power_state(client: data->client, on: false); |
215 | return ret; |
216 | } |
217 | } |
218 | |
219 | data->event_enabled[mma_axis] = state; |
220 | |
221 | return ret; |
222 | } |
223 | |
224 | static int mma9551_write_event_config(struct iio_dev *indio_dev, |
225 | const struct iio_chan_spec *chan, |
226 | enum iio_event_type type, |
227 | enum iio_event_direction dir, |
228 | int state) |
229 | { |
230 | struct mma9551_data *data = iio_priv(indio_dev); |
231 | int ret; |
232 | |
233 | switch (chan->type) { |
234 | case IIO_INCLI: |
235 | mutex_lock(&data->mutex); |
236 | ret = mma9551_config_incli_event(indio_dev, |
237 | axis: chan->channel2, state); |
238 | mutex_unlock(lock: &data->mutex); |
239 | return ret; |
240 | default: |
241 | return -EINVAL; |
242 | } |
243 | } |
244 | |
245 | static int mma9551_write_event_value(struct iio_dev *indio_dev, |
246 | const struct iio_chan_spec *chan, |
247 | enum iio_event_type type, |
248 | enum iio_event_direction dir, |
249 | enum iio_event_info info, |
250 | int val, int val2) |
251 | { |
252 | struct mma9551_data *data = iio_priv(indio_dev); |
253 | int ret; |
254 | |
255 | switch (chan->type) { |
256 | case IIO_INCLI: |
257 | if (val2 != 0 || val < 1 || val > 10) |
258 | return -EINVAL; |
259 | mutex_lock(&data->mutex); |
260 | ret = mma9551_update_config_bits(client: data->client, |
261 | MMA9551_APPID_TILT, |
262 | MMA9551_TILT_CFG_REG, |
263 | MMA9551_TILT_ANG_THRESH_MASK, |
264 | val); |
265 | mutex_unlock(lock: &data->mutex); |
266 | return ret; |
267 | default: |
268 | return -EINVAL; |
269 | } |
270 | } |
271 | |
272 | static int mma9551_read_event_value(struct iio_dev *indio_dev, |
273 | const struct iio_chan_spec *chan, |
274 | enum iio_event_type type, |
275 | enum iio_event_direction dir, |
276 | enum iio_event_info info, |
277 | int *val, int *val2) |
278 | { |
279 | struct mma9551_data *data = iio_priv(indio_dev); |
280 | int ret; |
281 | u8 tmp; |
282 | |
283 | switch (chan->type) { |
284 | case IIO_INCLI: |
285 | mutex_lock(&data->mutex); |
286 | ret = mma9551_read_config_byte(client: data->client, |
287 | MMA9551_APPID_TILT, |
288 | MMA9551_TILT_CFG_REG, val: &tmp); |
289 | mutex_unlock(lock: &data->mutex); |
290 | if (ret < 0) |
291 | return ret; |
292 | *val = tmp & MMA9551_TILT_ANG_THRESH_MASK; |
293 | *val2 = 0; |
294 | return IIO_VAL_INT; |
295 | default: |
296 | return -EINVAL; |
297 | } |
298 | } |
299 | |
300 | static const struct iio_event_spec mma9551_incli_event = { |
301 | .type = IIO_EV_TYPE_ROC, |
302 | .dir = IIO_EV_DIR_RISING, |
303 | .mask_separate = BIT(IIO_EV_INFO_ENABLE), |
304 | .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE), |
305 | }; |
306 | |
307 | #define MMA9551_INCLI_CHANNEL(axis) { \ |
308 | .type = IIO_INCLI, \ |
309 | .modified = 1, \ |
310 | .channel2 = axis, \ |
311 | .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ |
312 | .event_spec = &mma9551_incli_event, \ |
313 | .num_event_specs = 1, \ |
314 | } |
315 | |
316 | static const struct iio_chan_spec mma9551_channels[] = { |
317 | MMA9551_ACCEL_CHANNEL(IIO_MOD_X), |
318 | MMA9551_ACCEL_CHANNEL(IIO_MOD_Y), |
319 | MMA9551_ACCEL_CHANNEL(IIO_MOD_Z), |
320 | |
321 | MMA9551_INCLI_CHANNEL(IIO_MOD_X), |
322 | MMA9551_INCLI_CHANNEL(IIO_MOD_Y), |
323 | MMA9551_INCLI_CHANNEL(IIO_MOD_Z), |
324 | }; |
325 | |
326 | static const struct iio_info mma9551_info = { |
327 | .read_raw = mma9551_read_raw, |
328 | .read_event_config = mma9551_read_event_config, |
329 | .write_event_config = mma9551_write_event_config, |
330 | .read_event_value = mma9551_read_event_value, |
331 | .write_event_value = mma9551_write_event_value, |
332 | }; |
333 | |
334 | static irqreturn_t mma9551_event_handler(int irq, void *private) |
335 | { |
336 | struct iio_dev *indio_dev = private; |
337 | struct mma9551_data *data = iio_priv(indio_dev); |
338 | int i, ret, mma_axis = -1; |
339 | u16 reg; |
340 | u8 val; |
341 | |
342 | mutex_lock(&data->mutex); |
343 | |
344 | for (i = 0; i < 3; i++) |
345 | if (irq == data->irqs[i]) { |
346 | mma_axis = i; |
347 | break; |
348 | } |
349 | |
350 | if (mma_axis == -1) { |
351 | /* IRQ was triggered on 4th line, which we don't use. */ |
352 | dev_warn(&data->client->dev, |
353 | "irq triggered on unused line %d\n" , data->irqs[3]); |
354 | goto out; |
355 | } |
356 | |
357 | switch (mma_axis) { |
358 | case mma9551_x: |
359 | reg = MMA9551_TILT_YZ_ANG_REG; |
360 | break; |
361 | case mma9551_y: |
362 | reg = MMA9551_TILT_XZ_ANG_REG; |
363 | break; |
364 | case mma9551_z: |
365 | reg = MMA9551_TILT_XY_ANG_REG; |
366 | break; |
367 | } |
368 | |
369 | /* |
370 | * Read the angle even though we don't use it, otherwise we |
371 | * won't get any further interrupts. |
372 | */ |
373 | ret = mma9551_read_status_byte(client: data->client, MMA9551_APPID_TILT, |
374 | reg, val: &val); |
375 | if (ret < 0) { |
376 | dev_err(&data->client->dev, |
377 | "error %d reading tilt register in IRQ\n" , ret); |
378 | goto out; |
379 | } |
380 | |
381 | iio_push_event(indio_dev, |
382 | IIO_MOD_EVENT_CODE(IIO_INCLI, 0, (mma_axis + 1), |
383 | IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING), |
384 | timestamp: iio_get_time_ns(indio_dev)); |
385 | |
386 | out: |
387 | mutex_unlock(lock: &data->mutex); |
388 | |
389 | return IRQ_HANDLED; |
390 | } |
391 | |
392 | static int mma9551_init(struct mma9551_data *data) |
393 | { |
394 | int ret; |
395 | |
396 | ret = mma9551_read_version(client: data->client); |
397 | if (ret) |
398 | return ret; |
399 | |
400 | return mma9551_set_device_state(client: data->client, enable: true); |
401 | } |
402 | |
403 | static int mma9551_gpio_probe(struct iio_dev *indio_dev) |
404 | { |
405 | struct gpio_desc *gpio; |
406 | int i, ret; |
407 | struct mma9551_data *data = iio_priv(indio_dev); |
408 | struct device *dev = &data->client->dev; |
409 | |
410 | for (i = 0; i < MMA9551_GPIO_COUNT; i++) { |
411 | gpio = devm_gpiod_get_index(dev, NULL, idx: i, flags: GPIOD_IN); |
412 | if (IS_ERR(ptr: gpio)) { |
413 | dev_err(dev, "acpi gpio get index failed\n" ); |
414 | return PTR_ERR(ptr: gpio); |
415 | } |
416 | |
417 | ret = gpiod_to_irq(desc: gpio); |
418 | if (ret < 0) |
419 | return ret; |
420 | |
421 | data->irqs[i] = ret; |
422 | ret = devm_request_threaded_irq(dev, irq: data->irqs[i], |
423 | NULL, thread_fn: mma9551_event_handler, |
424 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
425 | MMA9551_IRQ_NAME, dev_id: indio_dev); |
426 | if (ret < 0) { |
427 | dev_err(dev, "request irq %d failed\n" , data->irqs[i]); |
428 | return ret; |
429 | } |
430 | |
431 | dev_dbg(dev, "gpio resource, no:%d irq:%d\n" , |
432 | desc_to_gpio(gpio), data->irqs[i]); |
433 | } |
434 | |
435 | return 0; |
436 | } |
437 | |
438 | static const char *mma9551_match_acpi_device(struct device *dev) |
439 | { |
440 | const struct acpi_device_id *id; |
441 | |
442 | id = acpi_match_device(ids: dev->driver->acpi_match_table, dev); |
443 | if (!id) |
444 | return NULL; |
445 | |
446 | return dev_name(dev); |
447 | } |
448 | |
449 | static int mma9551_probe(struct i2c_client *client) |
450 | { |
451 | const struct i2c_device_id *id = i2c_client_get_device_id(client); |
452 | struct mma9551_data *data; |
453 | struct iio_dev *indio_dev; |
454 | const char *name = NULL; |
455 | int ret; |
456 | |
457 | indio_dev = devm_iio_device_alloc(parent: &client->dev, sizeof_priv: sizeof(*data)); |
458 | if (!indio_dev) |
459 | return -ENOMEM; |
460 | |
461 | data = iio_priv(indio_dev); |
462 | i2c_set_clientdata(client, data: indio_dev); |
463 | data->client = client; |
464 | |
465 | if (id) |
466 | name = id->name; |
467 | else if (ACPI_HANDLE(&client->dev)) |
468 | name = mma9551_match_acpi_device(dev: &client->dev); |
469 | |
470 | ret = mma9551_init(data); |
471 | if (ret < 0) |
472 | return ret; |
473 | |
474 | mutex_init(&data->mutex); |
475 | |
476 | indio_dev->channels = mma9551_channels; |
477 | indio_dev->num_channels = ARRAY_SIZE(mma9551_channels); |
478 | indio_dev->name = name; |
479 | indio_dev->modes = INDIO_DIRECT_MODE; |
480 | indio_dev->info = &mma9551_info; |
481 | |
482 | ret = mma9551_gpio_probe(indio_dev); |
483 | if (ret < 0) |
484 | goto out_poweroff; |
485 | |
486 | ret = pm_runtime_set_active(dev: &client->dev); |
487 | if (ret < 0) |
488 | goto out_poweroff; |
489 | |
490 | pm_runtime_enable(dev: &client->dev); |
491 | pm_runtime_set_autosuspend_delay(dev: &client->dev, |
492 | MMA9551_AUTO_SUSPEND_DELAY_MS); |
493 | pm_runtime_use_autosuspend(dev: &client->dev); |
494 | |
495 | ret = iio_device_register(indio_dev); |
496 | if (ret < 0) { |
497 | dev_err(&client->dev, "unable to register iio device\n" ); |
498 | goto err_pm_cleanup; |
499 | } |
500 | |
501 | return 0; |
502 | |
503 | err_pm_cleanup: |
504 | pm_runtime_dont_use_autosuspend(dev: &client->dev); |
505 | pm_runtime_disable(dev: &client->dev); |
506 | out_poweroff: |
507 | mma9551_set_device_state(client, enable: false); |
508 | |
509 | return ret; |
510 | } |
511 | |
512 | static void mma9551_remove(struct i2c_client *client) |
513 | { |
514 | struct iio_dev *indio_dev = i2c_get_clientdata(client); |
515 | struct mma9551_data *data = iio_priv(indio_dev); |
516 | |
517 | iio_device_unregister(indio_dev); |
518 | |
519 | pm_runtime_disable(dev: &client->dev); |
520 | pm_runtime_set_suspended(dev: &client->dev); |
521 | |
522 | mutex_lock(&data->mutex); |
523 | mma9551_set_device_state(client: data->client, enable: false); |
524 | mutex_unlock(lock: &data->mutex); |
525 | } |
526 | |
527 | static int mma9551_runtime_suspend(struct device *dev) |
528 | { |
529 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
530 | struct mma9551_data *data = iio_priv(indio_dev); |
531 | int ret; |
532 | |
533 | mutex_lock(&data->mutex); |
534 | ret = mma9551_set_device_state(client: data->client, enable: false); |
535 | mutex_unlock(lock: &data->mutex); |
536 | if (ret < 0) { |
537 | dev_err(&data->client->dev, "powering off device failed\n" ); |
538 | return -EAGAIN; |
539 | } |
540 | |
541 | return 0; |
542 | } |
543 | |
544 | static int mma9551_runtime_resume(struct device *dev) |
545 | { |
546 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
547 | struct mma9551_data *data = iio_priv(indio_dev); |
548 | int ret; |
549 | |
550 | ret = mma9551_set_device_state(client: data->client, enable: true); |
551 | if (ret < 0) |
552 | return ret; |
553 | |
554 | mma9551_sleep(MMA9551_DEFAULT_SAMPLE_RATE); |
555 | |
556 | return 0; |
557 | } |
558 | |
559 | static int mma9551_suspend(struct device *dev) |
560 | { |
561 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
562 | struct mma9551_data *data = iio_priv(indio_dev); |
563 | int ret; |
564 | |
565 | mutex_lock(&data->mutex); |
566 | ret = mma9551_set_device_state(client: data->client, enable: false); |
567 | mutex_unlock(lock: &data->mutex); |
568 | |
569 | return ret; |
570 | } |
571 | |
572 | static int mma9551_resume(struct device *dev) |
573 | { |
574 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); |
575 | struct mma9551_data *data = iio_priv(indio_dev); |
576 | int ret; |
577 | |
578 | mutex_lock(&data->mutex); |
579 | ret = mma9551_set_device_state(client: data->client, enable: true); |
580 | mutex_unlock(lock: &data->mutex); |
581 | |
582 | return ret; |
583 | } |
584 | |
585 | static const struct dev_pm_ops mma9551_pm_ops = { |
586 | SYSTEM_SLEEP_PM_OPS(mma9551_suspend, mma9551_resume) |
587 | RUNTIME_PM_OPS(mma9551_runtime_suspend, mma9551_runtime_resume, NULL) |
588 | }; |
589 | |
590 | static const struct acpi_device_id mma9551_acpi_match[] = { |
591 | {"MMA9551" , 0}, |
592 | {}, |
593 | }; |
594 | |
595 | MODULE_DEVICE_TABLE(acpi, mma9551_acpi_match); |
596 | |
597 | static const struct i2c_device_id mma9551_id[] = { |
598 | {"mma9551" , 0}, |
599 | {} |
600 | }; |
601 | |
602 | MODULE_DEVICE_TABLE(i2c, mma9551_id); |
603 | |
604 | static struct i2c_driver mma9551_driver = { |
605 | .driver = { |
606 | .name = MMA9551_DRV_NAME, |
607 | .acpi_match_table = ACPI_PTR(mma9551_acpi_match), |
608 | .pm = pm_ptr(&mma9551_pm_ops), |
609 | }, |
610 | .probe = mma9551_probe, |
611 | .remove = mma9551_remove, |
612 | .id_table = mma9551_id, |
613 | }; |
614 | |
615 | module_i2c_driver(mma9551_driver); |
616 | |
617 | MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>" ); |
618 | MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>" ); |
619 | MODULE_LICENSE("GPL v2" ); |
620 | MODULE_DESCRIPTION("MMA9551L motion-sensing platform driver" ); |
621 | MODULE_IMPORT_NS(IIO_MMA9551); |
622 | |